duanliaogui4133
duanliaogui4133
2015-03-10 15:29

获取File()后无法关闭golang tcp套接字

已采纳

Please see the code below:

    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])
                             }
                     }()
             }
    }

when the program start,I use telnet to connect the localhost:8888,after 3 seconds,the server will kill me out, but the socket status is still ESTABLISHED when I use netstat to watch.If I remove the File() function, the socket can be closed normally.How can I fix this?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • duanjing4667 duanjing4667 6年前

    This is caused by the FDs being put into blocking mode. Once that happens, you're no longer using the runtime network poller, and have to use the socket as if you were using blocking calls and multiple threads. Underneath, a blocking recv call on a socket can't be interrupted by a close in another thread.

    A workaround may be to force the FD back into non-blocking mode before closing it:

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

    You can also shutdown the socket for reading before calling close:

    conn.CloseRead()
    conn.Close()
    
    点赞 评论 复制链接分享

相关推荐