networking - TCPConn SetWriteDeadline 不工作

标签 networking go tcp network-programming timeout

我正在用 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/

相关文章:

python - 为什么这个套接字连接只允许1次发送和接收?

c - SO_KEEPALIVE : Set on the server socket or on a per-client basis?

python - 如何在 python 中从附近主机检索 MAC 地址?

linux - 在/proc/sockstat 中,哪些 TCP 状态算作 'inuse' 哪些算作 'alloc'?

go - 如何在 k8s 集群中使用 heapster 获取文件系统/使用情况

bash - sed: 1: "'/正则表达式/.. .": invalid command code '

networking - 机器学习在计算机网络领域的应用

android - 使用 Android 应用更改网络运营商

go - 优化 html/模板组合

java - 如何使用 TCP 连接同时接受多个客户端?