golang tcp套接字在获取文件()后无法关闭

golang tcp socket can't close after get File()

请看下面的代码:

    包主
    导入 "net"
    进口 "log"
    导入 "bufio"
    进口 "time"

    功能主要(){
             l,_:=net.Listen("tcp", ":8888")
             为了 {
                     conn, _ := l.Accept()
                     log.Println("get conn", conn.RemoteAddr())
                     去功能(){
                             f, _:=conn.(*net.TCPConn).File()
                             d:=f.Fd()
                             log.Println(d)
                             f.Close()
                             arr := make([]字节, 1000)
                             reader := bufio.NewReader(conn)
                             time.AfterFunc(3*time.Second, func() {
                                     log.Println("close conn", conn.RemoteAddr())
                                     conn.Close()
                             })
                             为了 {
                                     大小,错误 := reader.Read(arr)
                                     如果错误!=无{
                                             休息
                                     }
                                     log.Println("sss", arr[:size])
                             }
                     }()
             }
    }

当程序启动时,我使用telnet连接localhost:8888,3秒后,服务器将我杀死,但是当我使用netstat连接watch.If时,套接字状态仍然是ESTABLISHED我删除了 File() 函数,套接字可以关闭 normally.How 我可以解决这个问题吗?

这是由于 FD 被置于阻塞模式引起的。一旦发生这种情况,您就不再使用运行时网络轮询器,并且必须像使用阻塞调用和多线程一样使用套接字。在下面,套接字上的阻塞 recv 调用不能被另一个线程中的 close 中断。

解决方法可能是在关闭 FD 之前强制其返回非阻塞模式:

syscall.SetNonblock(int(d), true)
f.Close()

您也可以在调用关闭之前关闭套接字进行读取:

conn.CloseRead()
conn.Close()