Cửa sổ TCP được sử dụng để kiểm soát luồng giữa các đồng nghiệp trên kết nối. Với mỗi gói ACK, một máy chủ sẽ gửi một trường "kích thước cửa sổ". Trường này cho biết số lượng byte dữ liệu mà máy chủ lưu trữ có thể nhận được trước khi nó đầy. Người gửi không được phép gửi nhiều hơn số lượng dữ liệu đó.
Cửa sổ có thể đầy nếu khách hàng không nhận dữ liệu đủ nhanh. Nói cách khác, các bộ đệm TCP có thể lấp đầy trong khi ứng dụng đang làm một cái gì đó khác ngoài việc đọc từ ổ cắm của nó. Khi điều đó xảy ra, máy khách sẽ gửi một gói ACK với bộ bit "cửa sổ đầy đủ". Tại thời điểm đó, máy chủ được cho là dừng gửi dữ liệu. Bất kỳ gói nào được gửi đến máy có cửa sổ đầy đủ sẽ không nhận được không. Nếu một bộ đệm ở phía gửi cũng đầy, thì ứng dụng gửi sẽ chặn khi nó cố gắng ghi thêm dữ liệu vào ổ cắm. !)
Đây là ngăn xếp TCP. Nó có thể xảy ra vì nhiều lý do, nhưng cuối cùng nó chỉ có nghĩa là người gửi đang truyền nhanh hơn người nhận đang đọc.
Khi ứng dụng trên đầu nhận được quay lại để đọc từ ổ cắm, nó sẽ rút một số dữ liệu đệm, giúp giải phóng một số dung lượng.Người nhận sau đó sẽ gửi gói "cập nhật cửa sổ" để cho người gửi biết số lượng dữ liệu có thể truyền. Người gửi bắt đầu truyền dữ liệu đệm và lưu lượng truy cập sẽ lưu thông thường.
Tất nhiên, bạn có thể nhận được các quầy hàng lặp lại nếu máy thu luôn chậm.
Tôi đã diễn đạt điều này như thể người gửi và người nhận khác nhau, nhưng trên thực tế, cả hai đồng nghiệp đang trao đổi cập nhật cửa sổ với mọi gói ACK và cả hai bên đều có thể lấp đầy cửa sổ.
Thông báo chung là bạn không cần phải gửi gói cập nhật cửa sổ trực tiếp. Nó sẽ thực sự là một ý tưởng tồi để giả mạo một lên.
Về ngoại lệ bạn đang xem ... nó không có khả năng gây ra hoặc bị ngăn chặn bởi gói cập nhật cửa sổ. Tuy nhiên, nếu khách hàng không đọc đủ nhanh, bạn có thể mất dữ liệu. Trong máy chủ của bạn, bạn nên kiểm tra giá trị trả về từ các cuộc gọi Socket.write() của bạn. Nó có thể nhỏ hơn số byte bạn đang cố gắng viết. Điều này xảy ra nếu bộ đệm truyền của người gửi đầy, điều này có thể xảy ra trong một gian hàng TCP. Bạn có thể bị mất byte.
Ví dụ: nếu bạn đang cố gắng viết 8192 byte với mỗi cuộc gọi để viết, nhưng một trong các cuộc gọi trả về 5691, thì bạn cần phải gửi 2501 byte còn lại vào cuộc gọi tiếp theo. Nếu không, máy khách sẽ không thấy phần còn lại của khối 8K đó và tệp của bạn sẽ ngắn hơn ở phía máy khách hơn là phía máy chủ.
Lỗi-fu của tôi cho tôi biết đoạn cuối này rất có khả năng đã đóng đinh vấn đề. – caf
Giải thích tuyệt vời, cảm ơn! Chính xác những gì tôi cần. Tôi nghĩ rằng tôi đã tìm thấy nguyên nhân của ngoại lệ - khách hàng đã dự kiến dữ liệu trong một hình thức khác, hơi dài hơn so với những gì tôi đang gửi. – phpscriptcoder
+1 để có giải thích chi tiết! – Izza