当前位置: 首页 > 知识库问答 >
问题:

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

太叔烨霖
2023-03-14

请参阅下面的代码:

    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个答案

濮阳耀
2023-03-14

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

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

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

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

conn.CloseRead()
conn.Close()
 类似资料:
  • 在我的客户端/服务器应用程序中,我的客户端wiil与服务器通信有两个功能:客户端要么向服务器请求数据,要么发送数据,以便服务器保存。我对这两种方法都使用一个套接字,要使用的方法由发送的第一个字节定义。如果第一个字节是“1”,它将请求数据。如果是“2”,它将发送数据(数据字节在“2”字节之后发送)。它非常适合发送数据。但是当我请求数据时,只要我不读取客户端中的套接字流,它就可以工作。这就像如果我在发

  • 我是MongoDB的新手。我正在尝试在Ubuntu 13.0 LTS上安装MongoDb 3.0,这是Windows 7 Host上的VM。我已经成功安装了MongoDB(软件包等),但是当我执行命令时,我在“/var/log/mongob/mongod.log”日志文件中得到以下错误。有人能帮助我理解这个错误吗。Internet上没有与此相关的内容。 2015-04-23T00:12:00.87

  • 我转向你,在这件事上我一直把头撞在墙上。 我正在做一个小的socket编程,我可以看到当我把它放出来。println(“…”)while循环之前的代码行(in.readLine())它工作正常,但我需要它位于循环内部。 说清楚一点,我没有看到任何错误。我只是看不到此应用程序的客户端显示文本。它看起来好像在工作,但事实并非如此。此外,我也不控制该应用程序的客户端,它由通过TCP连接到此套接字侦听器应

  • 我关闭了服务器端的writer,因为它永远不会发送任何消息,而是只从客户端读取消息。它不会抛出任何异常,而是停留在我调用的任何与套接字相关的方法的位置,如reader.readline()和socket.setsotimeout()。 这个问题很容易解决,因为我只是不关闭作家。但是,我很好奇为什么套接字无法通信。

  • 我们在gitlab ci构建中使用Sonarqube进行代码分析,现在我们在使用mvn clean org时遇到了问题。jacoco:jacocomaven插件:准备代理安装-Dmaven。测验失败ignore=true-DskipTests sonar:sonar要运行gitlab管道,管道中的错误与问题Jenkins/sonar timeout:Socket closed相同。 sonarqu

  • 问题内容: 从堆栈溢出的其他帖子中应该可以正常工作 但由于某种原因,它只是挂在()上而从不打印。我知道对www.cnn.com的请求将对数据进行分块,但我至少应该从中读取一些信息,对吗? PS我知道这是不是做到这一点的最好办法,而且有像库和在那里,但我不能使用那些为这个项目(这是学校)。我必须使用图书馆 问题答案: 您忘记在请求行之后发送空白行: 此外,HTTP 1.1指定您应添加HTTP 1.1