2012-09-04 30 views
7

Tôi đang thử nghiệm truyền thông máy khách-máy chủ thông qua một ổ cắm TCP. Tôi đã viết các máy chủ trong C và tôi đang chạy nó trên một máy Linux và tôi đang sử dụng nc như là một khách hàng để thử nghiệm.Chỉ có đường ống bị hỏng ở lần gửi thứ hai trên ổ cắm kín

Máy chủ, sau khi trao đổi tin nhắn ban đầu với khách hàng, gửi một số tin nhắn định kỳ cho khách hàng mà không nhận được bất kỳ phản hồi nào.

Nếu tôi giết khách hàng, tôi hy vọng rằng các send() đầu tiên thực hiện bởi các máy chủ không thành công với EPIPE lỗi nhưng điều này hóa ra chỉ ở thứ hai send() sau khi khách hàng đã biến mất! Đầu tiên send() sau khi tôi đã giết khách hàng có thể gửi thành công 1100 byte đến ổ cắm (tôi cho là đã đóng). Hoạt động send() sau kết thúc bằng EPIPE khi được exepcted.

Có ai có thể giải thích cho tôi về hành vi này không? Có phải do thực tế là tôi ghi vào ngăn xếp TCP/IP sao cho nó xếp chồng lên nhau để phân phối khi có thể? Nếu có, làm cách nào để kiểm tra trạng thái kết nối? Để chắc chắn người ngang hàng vẫn ở đó.

Trả lời

4

Kết nối TCP thông thường là bắt tay bốn chiều.

http://en.wikipedia.org/wiki/Transmission_Control_Protocol

Khi bạn đang giết chết các khách hàng phân khúc FIN được gửi từ phía khách hàng đến máy chủ và các giao thức máy chủ đống gửi ACK. Ở đây nếu máy chủ cố gắng đọc dữ liệu, cuộc gọi đọc sẽ trả về giá trị là 0, vì vậy chương trình máy chủ của bạn có thể hiểu rằng đồng đẳng đã đóng và bình thường sẽ đóng ổ cắm kết nối sau này. Điều này sẽ cho phép FIN từ phía máy chủ được gửi và bắt tay 4 chiều thông thường sẽ được hoàn thành sau khi nhận được ACK cuối cùng từ phía máy khách.

(Pl đọc Q 2.1 http://www.faqs.org/faqs/unix-faq/socket/)

Nhưng ở đây bạn đang ghi dữ liệu từ máy chủ, do đó máy chủ là nhận được một Reset từ khách hàng chỉ sau khi gửi dữ liệu. Vì vậy, bạn đang nhận được lỗi sau khi các hoạt động gửi đầu tiên đó là ngày gửi thứ hai.

Vì vậy, pl. cố gắng đóng kết nối từ phía máy khách đột ngột thay vì 4 cách, bằng cách đặt tùy chọn chuông và thời gian chờ là 0, để bạn có thể gặp lỗi (có thể khác với EPIPE) trong lần gọi đầu tiên gửi phía máy chủ. (Đây không phải là một thực hành recommnended nhưng chỉ cho hiểu biết của bạn trong trường hợp đặc biệt này)

Try the following option of nc, nc -L 0 to set the linger option and timeout to 0 

(tôi đã không thử tùy chọn này của nc, pl. kiểm tra để biết chi tiết trong liên kết này http://docs.oracle.com/cd/E23824_01/html/821-1461/nc-1.html)

Ví dụ về nc từ trang web trên,

Connect to TCP port, send some data and terminate the connection with 
TCP RST segment 
(instead of classic TCP closing handshake) by setting the linger option and 
timeout to 0: 

$ echo "foo" | nc -L 0 host.example.com 22 
+0

Cảm ơn câu trả lời của bạn, chi tiết và rõ ràng. Thật không may tôi không thể kiểm tra các tùy chọn nc bạn đề nghị tôi vì lệnh trên máy Linux của tôi dường như không hỗ trợ nó.Nhân tiện các tài liệu mà bạn đã chỉ cho tôi và các giải thích bạn đã cho tôi rõ ràng và hữu ích. Cảm ơn! – Igor

Các vấn đề liên quan