Plainnotes

close 和 shutdown 不是一回事

2024-07-18 · 3 分钟网络

写网络程序时,close(fd) 之后对端迟迟收不到 FIN,连接半开着。常见原因是还有别的地方持有这个 fd 的引用——fork 出来的子进程、dup 出来的副本,引用计数不为零,内核不会发 FIN。

shutdown(fd, SHUT_WR) 则立刻发 FIN,不管有几个引用,而且这个方向的写就结束了,读还能继续。这就是 HTTP 服务器常用的“半关闭”:告诉客户端“我说完了”,然后继续读请求。

另一个区别:shutdown 对 socket 有效,close 对所有 fd 有效。文件描述符是 socket 时两者才可比。

排查半开连接时,ss -tan 里的 FIN-WAIT-1、CLOSE-WAIT 状态能看出是谁没关。