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

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

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

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

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

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

  2. 被socked的服务器没有关闭,但是它读取了0个字节。(来自的返回值read()只是简单的0),剩下的仍然是设计者如何处理来自读取的返回值。但是即使服务器端套接字没有关闭,服务器什么时候发送它的FIN 位?在它完成执行后(以完成完全连接终止)?

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

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

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

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

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

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

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

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