TCP Write后直接Close安全吗?

我在实现服务器发送一个网页给浏览器的功能时,发现如果只是设置了 HTTP 头中的 Connection: close,浏览器不一定会保证在收到所有数据后关闭连接。也就是说,寄希望于设置了这个字段后浏览器会主动关闭连接是不现实的,虽然大多数浏览器都遵循这个字段。

因此,实现发送数据后服务器主动关闭连接是有必要的。

如果希望 TCP 在数据发送完成后就关闭,直接 write(fd, ...) 所有所需数据后再调用 close(fd) 能实现这个效果吗?

答案是可以的。TCP 协议栈会保证所有写入到内核缓冲区的数据都被可靠地发送后,再发送 FIN 包。 也就是说,只要做到 写完再关,就能确保浏览器能完整收到所有数据。

但需要注意的是,TCP 在这里的“可靠”,并不意味着“必达”。 TCP 保证的是:要么成功发送到对端,要么网络断开或不可达。

一些要点

  • 非阻塞写场景下,很容易出现部分写(Partial Write),需要确保所有数据都被写入内核缓冲区后再关闭才是安全的。
  • 默认的 close 是优雅关闭,会等待所有数据发送完成后再发送 FIN 包。
  • 如果对端提前关闭,会导致写返回 EPIPE 或触发 SIGPIPE,这两种情况都需要处理:应该直接关闭。