简体   繁体   中英

Detecting a TCP reset with Linux sockets

When one end of a TCP link disconnects, it sends a reset (RST) message to the other end. I want to be able to receive this in the application layer.

In my code, I use a select() call to receive input from potentially multiple sources, including a TCP connection. I've seen that when the select() shows that there is data ready to read on the connection, and then a read() call returns 0 bytes read, that happened after a RST was sent over TCP. (I understand recv() works similarly to read() .)

Does read() return 0 bytes (after select() ) on a TCP connection only if the connection was reset? Does it ever return 0 bytes in any other cases?

I remember a while ago using a particular ethernet device on the other end of the connection, and this Linux end was receiving 0 bytes after a select() , but not for a connection reset, but rather mid-way through some data streaming. I confirmed in Wireshark that the packet received had 0 data bytes. Is this a bug, or like the question above, is it valid to have this behaviour? I can't remember which device it was, as it was a few years back, but it was using a Windows driver.

When one end of a TCP link disconnects, it sends a reset (RST) message to the other end.

Not normally.

I want to be able to receive this in the application layer.

You will.

I've seen that when the select() shows that there is data ready to read on the connection, and then a read() call returns 0 bytes read, that happened after a RST was sent over TCP.

No.

Does read() return 0 bytes (after select()) on a TCP connection only if the connection was reset?

Never if the connection was reset. It returns -1 with errno == ECONNRESET in that case.

Does it ever return 0 bytes in any other cases?

It returns zero if and only if a FIN was received, ie the peer closed the connection, or shutdown his socket for output.

You also get a RST if you try to connect to a port at a server for which there is no listener.

Suppose you have a connection to a server and send data to it regularly, but then the server reboots, your socket pair does not exist anymore of course and then you also get a RST.

It is possible for a server to send a RST, by using socket options I believe, but this is not a good idea, servers/clients should use a normal close on a socket in normal situations where they want to close the communication, and let TCP's 4 way handshake do its thing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM