请参阅以下代码:
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()功能,套接字可以正常关闭。我该如何解决这个问题?
答案 0 :(得分:6)
这是由FD进入阻塞模式引起的。一旦发生这种情况,您就不再使用运行时网络轮询器,并且必须像使用阻塞调用和多个线程一样使用套接字。在下面,套接字上的阻止recv
调用不能被另一个线程中的close
中断。
解决方法可能是在关闭FD之前强制FD返回非阻塞模式:
syscall.SetNonblock(int(d), true)
f.Close()
您也可以在调用close之前关闭套接字以进行读取:
conn.CloseRead()
conn.Close()