如果 ESTABLISHED 套接字(从客户端通过 连接后connect()
)退出并因此内核关闭所有打开的文件描述符,另一端会发生什么?如果客户端发送 FIN 并且服务器确认它(这只是半关闭状态),但服务器尝试read()
在该套接字上,那么会发生什么?我可以想象两种情况:
套接字服务器read()
已打开,也已关闭。但是在服务器端没有exit(),所以没有人在该端关闭那个套接字。所以在这里我不知道服务器是如何结束的,因为它的那个套接字的末端不应该被关闭
被socked的服务器没有关闭,但是它读取了0个字节。(来自的返回值read()
只是简单的0
),剩下的仍然是设计者如何处理来自读取的返回值。但是即使服务器端套接字没有关闭,服务器什么时候发送它的FIN 位?在它完成执行后(以完成完全连接终止)?
这是服务器端从关闭的套接字读取的语句(在客户端关闭):
while ((len = read(sockfd, buf, 256)) > 0){
...
}
在这里,它会因为read()
读取关闭而返回sockfd
吗?还是因为read()
返回 0 从而使条件为假?(上述2种情况)。据我所知,如果read()
在关闭的 fd 上读取,则错误将返回(-1)。但是 0 字节读取只是返回 (0)。那么返回的是什么?
连接的关闭意味着两个对等方都同意他们不想再相互通信。如果只有一个对等方关闭套接字,它只是与 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
.
请检查编辑。是否
read()
返回-1或0?@milanHrabos:“read() 返回 -1 还是 0?” - 请参阅更新的答案。
@milanHrabos:“不是说对方必须以某种方式处理 RST 响应吗?” - 没有回复 RST。在套接字上接收 RST 时的处理是关闭套接字,因为显然与客户端的连接不再有效。
@milanHrabos:
read
仅在当前没有要读取的字节但将来可能有字节时才阻塞,即等待新数据有意义时。如果客户端明确表示将不再发送更多数据(即 FIN),read
则将不再等待更多数据 - 即返回 0。@milanHrabos 它在内核中的套接字接收缓冲区为空且未收到 FIN 且未发生错误时阻塞。