如何在 Go 中刷新 tcp 套接字?

How do I flush a tcp socket in Go?

如何在 Go 中刷新 tcp 套接字?

我正在通过套接字一次发送一条消息,向客户端指示进度,但这些消息会聚在一起并同时发送。我在任何地方都看不到冲洗功能。

消息每隔几秒发送一次,每条小于 100 字节,我将它们发送到本地主机。通过冲洗,我的意思是我想清除所有缓冲区以阻止它们从电线上掉下来;在这种情况下,它们显然在某个地方被缓冲了。

如果 Go 不暴露这个,我能不能深入地狱去冲洗底层 buffer/socket 自己?

正如@JimB 提到的,您不能 Flush() net.Conn,因此如果您的数据流停滞不前,则说明它正在其他地方进行缓冲。

如果您或数据流中的中间包正在使用 bufio:

w := bufio.NewWriter(conn)

if _, err := w.WriteString(msg); err != nil {
   return err
}

w.Flush()

虽然 conn 无法刷新,但 bufio.Writer 可以。

但是,如果您的连接是作为纯 io.Writer 类型提供给您的(即仅 Write() 方法 - 没有 Flush()),您可以尝试运行时 conversion/check看看是不是"flushable":

// var connWriter io.Writer

type Flusher interface {
    // Flush sends any buffered data to the client.
    Flush() error
}

flushable, ok := connWriter.(Flusher) // runtime interface/type check

if !ok {
    log.Println("flushing not supported")
    return
}

flushable.Flush()

啊!它在 bash 管道中在客户端进行缓冲。删除了我必须尝试测量响应之间经过的时间的 | ts -s '%.T',现在它可以工作了。

brew install expectunbuffer my-command -a -b --foo | ts -s '%.T' 根据 mac、linux 此处的建议解决此问题 https://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe

问题悬而未决,因为我对我提出的问题得到了很好的回答,这可能会对其他人有所帮助。