为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕莱坞森 2021-09-20 20:36:24
请看下面的代码:    包主    导入“网”    导入“日志”    导入“bufio”    导入“时间”    功能主(){             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.关闭()                             arr := make([]byte, 1000)                             读者 := bufio.NewReader(conn)                             time.AfterFunc(3*time.Second, func() {                                     log.Println("close conn", conn.RemoteAddr())                                     conn.Close()                             })                             为了 {                                     大小,错误:= reader.Read(arr)                                     如果错误!= nil {                                             休息                                     }                                     log.Println("sss", arr[:size])                             }                     }()             }    }程序启动时,我用telnet连接localhost:8888,3秒后,服务器把我杀了,但是我用netstat看时socket状态还是ESTABLISHED。如果去掉File()函数,插座可以正常关闭。我该如何解决?
查看完整描述

1 回答

?
aluckdog

TA贡献1847条经验 获得超7个赞

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


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


syscall.SetNonblock(int(d), true)

f.Close()

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


conn.CloseRead()

conn.Close()


查看完整回答
反对 回复 2021-09-20
  • 1 回答
  • 0 关注
  • 292 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信