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.
While analyzing the packet capture select the RST packet and right-click and select Conversation filter and then select TCP. This will filter the packets for the selected conversation only and make it easy to troubleshoot. From the packet capture, the client sends the SYN for TCP handshake and gets RST from the server.
You could check if the socket is still connected by trying to write to the file descriptor for each socket. Then if the return value of the write is -1 or if errno = EPIPE, you know that socket has been closed.
An application gets a connection reset by peer error when it has an established TCP connection with a peer across the network, and that peer unexpectedly closes the connection on the far end.
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, i.e. the peer closed the connection, or shutdown his socket for output.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With