我正在 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
不是正确的方法,我该怎么办?答案 0 :(得分:0)
这结果是一个僵局问题。
我的程序每次使用扇出模式在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
}