Chuyển tiếp nửa đóng TCP sau khi xả hết các byte đang chờ
Xử lý EOF trong proxy TCP mà không bỏ mất dữ liệu trong hàng đợi hay cắt ngang phản hồi ở chiều ngược lại.
Máy khách gửi xong, proxy thấy EOF, và phản hồi biến mất. Đóng cả hai socket của proxy ngay lập tức có thể gây ra đúng trình tự đó. Trong một relay TCP, kết thúc có trật tự ở một chiều không có nghĩa là chiều kia đã xong.
Hãy xét một máy khách gửi yêu cầu, đóng phía gửi của mình và chờ câu trả lời:
client -- request, then FIN --> proxy --> service
client <-------- reply ------- proxy <-- service
Proxy có hai kết nối TCP và hai luồng byte chuyển động độc lập. Nó phải chuyển tiếp dấu hiệu kết thúc dữ liệu vào, sau khi đã chuyển tiếp các byte đi trước dấu hiệu đó.
Xả hàng đợi trước khi chuyển tiếp EOF
Với một lần nhận có kích thước khác không trên luồng TCP, việc trả về 0 cho biết luồng đến đó đã kết thúc có trật tự. Đánh dấu chiều đọc đó là đã xong. Ngừng chờ thêm dữ liệu vào từ nó, nhưng giữ lại các byte đã được xếp hàng cho socket đối diện.
Khi hàng đợi từ máy khách tới dịch vụ đã cạn, gọi shutdown(service_socket, SHUT_WR) trên socket POSIX. Lệnh này kết thúc việc truyền tiếp về phía dịch vụ trong khi vẫn để chiều từ dịch vụ tới máy khách khả dụng. Khi dịch vụ hoàn tất phản hồi, áp dụng thao tác đối xứng sau khi xả hàng đợi phản hồi.
Việc đóng các bộ mô tả thuộc về thời điểm cả hai chiều và các bộ đệm đang chờ của chúng đã xong, hoặc khi một lỗi hay việc hủy bỏ đòi hỏi phải kết thúc. Giữ một thời gian chờ có giới hạn cho một bên không bao giờ hoàn tất nửa còn lại của mình.
Sự sẵn sàng là lời mời đọc
Một socket đọc được có thể có dữ liệu hoặc trạng thái EOF. Gọi recv và diễn giải kết quả. Số dương là số byte cần chuyển tiếp; số 0 là điểm cuối của chiều. Trên socket không chặn, EAGAIN hoặc EWOULDBLOCK nghĩa là hiện không còn dữ liệu vào, trong khi EINTR có thể cần thử lại. Không cái nào là cùng một sự kiện như EOF.
Đừng tìm cờ FIN trong bộ đệm byte được trả về. TCP giao cho API này một luồng byte có thứ tự; ranh giới gói tin và phân đoạn FIN không phải là tải trọng ứng dụng thông thường.
Đây là vòng đời của một đường hầm byte thô. Một proxy HTTP phân tích thông điệp vẫn phải tôn trọng cách đóng khung HTTP, và một proxy kết thúc TLS cũng có giao thức đóng TLS. Hãy giữ những quyết định giao thức đó ở trên relay TCP theo chiều.