2015-05-22 13 views
5

Khi một đầu của liên kết TCP ngắt kết nối, nó sẽ gửi thông báo đặt lại (RST) đến đầu kia. Tôi muốn có thể nhận được điều này trong lớp ứng dụng.Phát hiện đặt lại TCP với ổ cắm Linux

Trong mã của mình, tôi sử dụng cuộc gọi select() để nhận dữ liệu nhập từ nhiều nguồn tiềm năng, bao gồm kết nối TCP. Tôi đã thấy rằng khi select() cho thấy rằng có sẵn dữ liệu để đọc trên kết nối và sau đó cuộc gọi read() trả về 0 byte đã đọc, điều đó đã xảy ra sau khi RST được gửi qua TCP. (Tôi hiểu recv() công trình tương tự như read().)

Liệu read() return 0 byte (sau select()) trên một kết nối TCP chỉ khi kết nối được thiết lập lại? Liệu nó có bao giờ trả lại 0 byte trong bất kỳ trường hợp nào khác không?

Tôi nhớ một thời gian trước đây sử dụng một thiết bị ethernet đặc biệt ở đầu bên kia của kết nối, và kết thúc Linux này đã nhận được 0 byte sau một select(), nhưng không phải cho một thiết lập lại kết nối, mà đúng hơn là giữa đường thông qua một số dữ liệu phát trực tuyến. Tôi xác nhận trong Wireshark rằng gói nhận được có 0 byte dữ liệu. Đây có phải là một lỗi, hoặc giống như câu hỏi trên, liệu có hợp lệ để có hành vi này không? Tôi không thể nhớ đó là thiết bị nào, vì nó đã được một vài năm trở lại, nhưng nó đã được sử dụng một trình điều khiển Windows.

+0

Lưu ý rằng người ta nên đọc câu hỏi mà tôi đã dự định bằng cách thay thế tinh thần "reset/RST" bằng "finish/FIN". Tôi vặn vẹo câu hỏi khi tôi viết nó. –

+0

Sau đó, đơn giản, bạn đọc 0 byte từ ổ cắm nếu đồng đẳng đã đóng kết nối của nó bằng cách sử dụng đóng bình thường. Đây là đồng đẳng nói rằng tôi sẽ không còn gửi bất cứ điều gì cho bạn và nó được gọi là một nửa gần. –

Trả lời

9

Khi một đầu của liên kết TCP ngắt kết nối, nó sẽ gửi thông báo đặt lại (RST) đến đầu kia.

Không bình thường.

Tôi muốn có thể nhận được điều này trong lớp ứng dụng.

Bạn sẽ.

Tôi đã thấy rằng khi select() cho thấy có sẵn dữ liệu để đọc trên kết nối, sau đó gọi read() trả về 0 byte đọc, xảy ra sau khi RST được gửi qua TCP.

số

Liệu read() return 0 byte (sau khi chọn()) trên một kết nối TCP chỉ khi kết nối được thiết lập lại?

Không bao giờ nếu kết nối được đặt lại. Nó trả về -1 với errno == ECONNRESET trong trường hợp đó.

Nó có bao giờ trả về 0 byte trong bất kỳ trường hợp nào khác không?

Nó trả về số không nếu và chỉ khi nhận được FIN, tức là đồng đẳng đóng kết nối hoặc tắt ổ cắm của mình cho đầu ra.

+0

Trả về 'read()' tiếp theo là gì? –

+0

giá trị âm. Vì đây là lỗi. –

+1

Nếu bạn lặp lại một trong những lần đọc ở trên, bạn sẽ nhận được kết quả tương tự một lần nữa. Vì vậy, không. Bạn nên đã đóng socket lần đầu tiên bạn có 0 hoặc -1, với việc thực thi duy nhất thời gian chờ đọc (-1/EAGAIN/EWOULDBLOCK). – EJP

0

Bạn cũng nhận được RST nếu bạn cố gắng kết nối với cổng tại máy chủ không có người nghe.

Giả sử bạn có kết nối với máy chủ và gửi dữ liệu đến máy chủ thường xuyên, nhưng sau đó máy chủ khởi động lại, cặp socket của bạn không còn tồn tại nữa và sau đó bạn cũng nhận được RST.Có thể cho một máy chủ gửi RST, bằng cách sử dụng các tùy chọn ổ cắm tôi tin, nhưng đây không phải là một ý tưởng hay, máy chủ/máy khách nên sử dụng đóng bình thường trên ổ cắm trong các tình huống bình thường mà họ muốn đóng giao tiếp, và để cho cái bắt tay 4 chiều của TCP làm việc của nó.

+0

Cảm ơn, nhưng tôi đã làm hỏng câu hỏi và nói RST thay vì FIN ...: \ –

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