net.conn.write仅将数据写入内核发送缓冲区,不保证全部发出,需检查返回值n和err,不重试、不分包、不处理粘包。
Go 中用 net.Conn.Write 发送 TCP 数据最直接
只要拿到一个已建立连接的 net.Conn,调用它的 Write 方法就能发数据。它底层就是系统调用 send() 的封装,不带重试、不自动分包、不处理粘包——你给什么字节,它就原样往 socket 里塞。
常见错误是写完没检查返回值,或者误以为 Write 会阻塞到全部数据发出(其实只保证写入内核发送缓冲区成功):
-
Write返回实际写入字节数和可能的错误;若n ,说明缓冲区满或连接异常,需手动重试 - 不要假设一次
Write就能把整个消息发出去,尤其在高负载或小窗口时 - 如果服务端按行或按长度解析,必须自己加协议头或换行符,
Write不会帮你做
conn, _ := net.Dial("tcp", "127.0.0.1:8080")
n, err := conn.Write([]byte("HELLO\n"))
if err != nil {
log.Fatal(err)
}
if n < len("HELLO\n") {
// 需要补发剩余部分
}
用 bufio.Writer 提升小数据频繁发送的效率
每调用一次 Write 都是一次系统调用开销,如果连续发多个短消息(比如心跳、日志片段),直接裸写效率低且易触发 Nagle 算法延迟。
bufio.Writer 提供用户态缓冲,把多次 Write 合并成一次系统调用,适合「攒一批再发」的场景: