我正在用 Golang 编写一个 TCP 客户端。服务器永远不会发送任何回复或任何数据。
一旦我在给定的超时后无法写入,我希望客户端关闭连接。
因此,通过阅读 Conn
中的 SetWriteDeadline
文档:
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
不是正确的方法,我该怎么做?
最佳答案
这是一个死锁问题。
我的程序每次使用扇出模式在 messages
channel 上发送时都使用锁。
问题是,当我在写入超时时返回 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/