我正在使用 Golang 编写一个TCP客户端。服务器将永远不会发送任何答复或任何数据。
给定的超时后,如果我无法写入,我希望客户端关闭连接。
因此,通过阅读SetWriteDeadline
中的Conn
文档:
https://golang.org/pkg/net/#Conn
// SetWriteDeadline sets the deadline for future Write calls
// and any currently-blocked Write call.
// Even if write times out, it may return n > 0, indicating that
// some of the data was successfully written.
// A zero value for t means Write will not time out.
SetWriteDeadline(t time.Time) error
从上面的描述中,我可以这样使用它:
...
for {
select {
case msg := <-messages:
conn.SetWriteDeadline(time.Now().Add(1 * time.Second))
// When server goes away this just blocks forever. No timeout!
n, err := conn.Write(msg.ByteArray())
if err != nil {
return err
}
log.Printf("Sent %v bytes\n", n)
}
}
...
但是,如果服务器消失,则永远不会触发超时,相反,
Write
调用将永远阻塞。SetWriteDeadline
在做什么? SetWriteDeadline
不是执行此操作的正确方法,我该怎么做? 最佳答案
原来这是一个僵局问题。
我的程序每次使用Fanout模式在messages
通道上发送时都使用锁。
问题是,当我在写入超时时返回err
时,有一个defer
调用试图锁定同一Mutex
。因为我没有得到输出,所以我以为超时就不会触发。
defer func() {
thing.ThatCreatedDeadlock()
log.Println("Expected to see this")
}
因此,直接登录
Write
错误将使这一点显而易见: n, err := conn.Write(msg.ByteArray())
if err != nil {
log.Println(err)
return err
}
关于networking - TCPConn SetWriteDeadline无法正常工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46759513/