Go TCP 读取是非阻塞的:解决不完整的数据接收
在 Go 中,TCP 读取是非阻塞的,这意味着它们立即返回任何可用的数据,即使它低于预期。此行为与 C 的阻塞读取不同,C 的阻塞读取会等到收到所需的数据量为止。
非阻塞读取的原因
TCP 作为字节流运行,在传输过程中可能会出现碎片。因此,仅根据接收到的字节数无法确定消息的结束。这就需要自定义分隔符或者其他机制来确定消息边界。
数据不完整的解决方案
要读取特定数量的字节,请使用 io.ReadAtLeast 或 io.ReadFull 。对于任意条件,循环读取调用,直到没有错误或满足指定条件为止。
示例:
package main
import (
"fmt"
"net"
"time"
)
func main() {
conn, _ := net.Dial("tcp", "127.0.0.1:4243")
// Set a deadline to prevent hanging reads
_ = conn.SetReadDeadline(time.Now().Add(10 * time.Second))
// Loop to read until a newline is encountered
for {
buf := make([]byte, 512)
n, err := conn.Read(buf)
if err != nil {
fmt.Println(err)
break
}
if n > 0 {
str := string(buf[:n])
if str[len(str)-1] == '\n' {
fmt.Println(str)
break
}
}
}
}
其他注意事项
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3