Zach Dennis said:
If you have two sockets connected to eachother. Let's say...
a_socket and b_socket
And you tell a_socket to close, why does b_socket not know it is closed?
a_socket.close
b_socket.closed? => false
closed? is true only if you have called close() previously, i.e. if
you have closed the socket locally.
If the remote end closes its side, closed? would still return false if
you haven't called close() yet.
Detecting if the remote end has closed its side is not that
straight-forward.
Consider the following cases with TCP connection:
1. Your OS receives the FIN packet generated when the remote end does
a close(). select() will say that there is data to be read (the FIN
packet), and when you do a read, it will return with 0 data (since the
FIN packet is a transport-level business and does not contain
app-level data). if you try to write to such socket, you'll get EPIPE.
2. No FIN packet received because, say, the cable was hacked with an
axe. If you try to do a read(), read() will block until TCP times out
(2 hours?), same story with write(). That's because it is not possible
to determine if the cable has been chopped from software; for all the
TCP stack knows, it could have been just a network delay when it
doesn't immediately get any reply.
There is no rescuing for case #2, but case #1 is simply BSD socket
semantic. The BSD socket API does not have a mechanism to proactively
see if a FIN has been received. The mechanism must be triggered from
the calling app.
There may be mistakes in the above description as TCP is quite complex
and I don't profess full understanding of its intricacies. But I think
the broad idea is correct.
YS.