首页 文章

获取File()后golang tcp socket无法关闭

提问于
浏览
0

请参阅以下代码:

package main
    import "net"
    import "log"
    import "bufio"
    import "time"

    func main() {
             l,_:=net.Listen("tcp", ":8888")
             for {
                     conn, _ := l.Accept()
                     log.Println("get conn", conn.RemoteAddr())
                     go func() {
                             f, _:=conn.(*net.TCPConn).File()
                             d:=f.Fd()
                             log.Println(d)
                             f.Close()
                             arr := make([]byte, 1000)
                             reader := bufio.NewReader(conn)
                             time.AfterFunc(3*time.Second, func() {
                                     log.Println("close conn", conn.RemoteAddr())
                                     conn.Close()
                             })
                             for {
                                     size, err := reader.Read(arr)
                                     if err != nil {
                                             break
                                     }
                                     log.Println("sss", arr[:size])
                             }
                     }()
             }
    }

当程序启动时,我使用telnet连接localhost:8888,3秒后,服务器会将我杀掉,但是当我使用netstat监视时套接字状态仍然是ESTABLISHED . 如果我删除了File()函数,套接字可以正常关闭 . 我该怎么解决这个问题?

1 回答

  • 6

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

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

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

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

    conn.CloseRead()
    conn.Close()
    

相关问题