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()
请看下面的代码:
包主 导入 "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()