Warm tip: This article is reproduced from serverfault.com, please click

Does close() on socket on one end, closes on the other end as well?

发布于 2021-01-01 22:53:49

If ESTABLISHED socket (after connecting from client via connect()), exits and thus kernel closes all open file descriptor, what happens to the other side? If the client sends FIN and the server ACK it (which is just half-closed state), but the server tries to read() on that socket, what happen then? I can imagine 2 situation:

  1. the socket server read()s on, is closed also. But in the server side there is no exit(), so noone has closed that socket at that side. So here I do not know how server ends, since its end of that socket should not be closed

  2. the server socked is not closed, but it reads 0 bytes. (the return value from read() is simply 0) and the rest remain on designer how to handle return value from read. But still even if the server side socket is not closed, when does the server sends its FIN bit? After it finishes execution (to complete full connection termination) ?

here is the statement at server side that reads from closed socket (closed at client side):

while ((len = read(sockfd, buf, 256)) > 0){
...
}

here, will it return because the read() reads on closed sockfd? or because the read() returns 0 and thus false the condition? (the 2 situation described above). As far as I know, if read() would read on closed fd, then error would be return (-1). But 0 bytes reads just return (0). So what is returned?

Questioner
milanHrabos
Viewed
0
Steffen Ullrich 2021-01-02 07:23:14

A close of a connection means that both peers agree that they don't want to communicate any more with each other. If only one peer closes the socket it just communicates with the FIN that it will no longer send any data. It also communicates to the local OS that it is no longer willing to receive any data - here close(sock) differs from shutdown(sock,SHUT_WR).

A call to read in the server will return 0 if the client closed or shutdown the socket, since this meant that no more data are send from client to server. The server then might decide to also close or shutdown the socket. But might also decide to send more data to the client, since the socket is not closed yet in the server. If the server sends more data the client will respond with a RST (connection reset) since it is not expecting any more data. When receiving the RST the server side socket gets automatically closed too.

while ((len = read(sockfd, buf, 256)) > 0){

In most cases read will return 0 here if the client has closed the connection. It will return -1 in case an error on the socket occurred, notably Connection reset. This might happen if the server has written data to the client while the client has already closed the connection (i.e. race condition), in which case the client will return with a RST. This error will be delivered on the next syscall on the socket, i.e. the read.