一端套接字上的 close() 是否也在另一端关闭?

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

如果 ESTABLISHED 套接字(通过 connect() 从客户端连接后)退出,因此内核关闭所有打开的文件描述符,另一端会发生什么?如果客户端发送 FIN 并且服务器对其进行 ACK(这只是半关闭状态),但是服务器尝试在该套接字上 read(),那么会发生什么?我可以想象两种情况:

  1. 套接字服务器 read()s 上,也已关闭。但是在服务器端没有 exit(),所以没有人关闭那一侧的套接字。所以在这里我不知道服务器是如何结束的,因为它的那个套接字的末端不应该被关闭

  2. 服务器未关闭,但读取了 0 个字节。 (来自 read() 的 return 值只是 0),其余的留给设计者如何处理来自读取的 return 值。但是即使服务器端套接字没有关闭,服务器什么时候发送 its FIN 位?完成执行后(完成完全连接终止)?

这是服务器端从关闭的套接字(在客户端关闭)读取的语句:

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

在这里,它会 return 因为 read() 读取关闭 sockfd 吗?还是因为 read() returns 0 从而使条件错误? (上述2种情况)。据我所知,如果 read() 将在关闭的 fd 上读取,则错误将是 return (-1)。但是 0 字节只读取 return (0)。那么什么是 returned?

关闭连接意味着双方都同意他们不想再相互通信。如果只有一个对等点关闭套接字,它只是与 FIN 通信,它将不再发送任何数据。它还通知本地 OS 它不再愿意接收任何数据 - 这里 close(sock) 不同于 shutdown(sock,SHUT_WR)

如果客户端关闭或关闭套接字,服务器中对 read 的调用将 return 0,因为这意味着不再有数据从客户端发送到服务器。然后服务器可能决定也关闭或关闭套接字。但也可能决定向客户端发送更多数据,因为服务器中的套接字尚未关闭。如果服务器发送更多数据,客户端将响应 RST(连接重置),因为它不再需要任何数据。收到 RST 时,服务器端套接字也会自动关闭。

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

在大多数情况下,如果客户端已关闭连接,read 将在此处 return 0。它会 return -1 以防套接字发生错误,特别是 Connection reset。如果服务器已将数据写入客户端而客户端已关闭连接(即竞争条件),则可能会发生这种情况,在这种情况下,客户端将 return 与 RST。此错误将在套接字上的下一个系统调用中传递,即 read.