【问题标题】:Does close() on socket on one end, closes on the other end as well?一端的套接字上的 close() 是否也在另一端关闭?
【发布时间】:2021-04-08 13:51:59
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 关闭一个套接字不会关闭另一个套接字。 1、接收到FIN的socket直到本地应用程序关闭后才处于关闭状态。在此之前它一直处于 CLOSE_WAIT 状态。 2.服务器在调用shutdown()close()时发送自己的FIN位。

标签: sockets tcp client-server


【解决方案1】:

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

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

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

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

【讨论】:

  • 请检查编辑。 read() 返回 -1 还是 0?
  • @milanHrabos:“read() 是返回 -1 还是 0?” - 查看更新后的答案。
  • @milanHrabos:“不是说对方必须以某种方式处理 RST 响应吗?” - 没有对 RST 的回复。在套接字上接收 RST 时的处理是关闭套接字,因为显然与客户端的连接不再有效。
  • @milanHrabos: read 仅在当前没有要读取的字节但将来可能存在时阻塞,即等待新数据有意义时。如果客户端明确表示将不再发送更多数据(即 FIN),那么read 也将不再等待更多数据 - 即返回 0。
  • @milanHrabos 在内核中的套接字接收缓冲区为空且未收到 FIN 且未发生错误时阻塞。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
相关资源
最近更新 更多