如何正确的关闭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 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!