如何正确的关闭tcp连接
linux的系统调用提供了两个方法去关闭tcp连接,他们有什么区别,我这里列个表格来看看
对比项 | close(fd) | shutdown(fd, 0) | shutdown(fd, 1) | shutdown(fd, 2) |
---|---|---|---|---|
含义 | 关闭读写端 | 关闭读端 | 关闭写端 | 关闭读写端 |
发送fin包 | 是 | 否 | 是 | 是 |
孤儿socket | 是 | 否 | 否 | 否 |
注意:执行shutdown后,若连接已经进入TIME-WAIT状态则是孤儿socket,在此之前不是。
如何测试以上的结论呢?写一个go程序如下:
// 服务端代码
package main
import (
"net"
)
func main() {
listener, _ := net.Listen("tcp", "localhost:6380")
for {
_, _ = listener.Accept()
}
}
// 客户端代码
package main
import (
"net"
"syscall"
)
func main() {
_, err := net.Dial("tcp", "localhost:6380")
if err != nil {
println(err.Error())
}
// 这里依次可以换成Shutdown(3, 1)、Shutdown(3, 2)、Close(3)
syscall.Shutdown(3, 0)
select {}
}
执行的时候进行抓包,即可看到fin包的发送情况。通过lsof -i :6380
查看是否是孤儿进程。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: