Go TCP 读取是非阻塞的:解决不完整的数据接收
在 Go 中,TCP 读取是非阻塞的,这意味着它们会立即返回任何可用的数据,即使它低于预期。此行为与 C 的阻塞读取不同,C 的阻塞读取会等待收到所需的数据量。
非阻塞读取的原因
TCP 作为字节流运行,在传输过程中可能会出现碎片。因此,仅根据接收到的字节数无法确定消息的结束。这就需要自定义分隔符或者其他机制来确定消息边界。
数据不完整的解决方案
要读取特定数量的字节,请使用 io.ReadAtLeast 或 io.ReadFull 。对于任意条件,循环读取调用,直到没有错误或满足指定条件。
示例:
<code class="go">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 } } } }</code>
其他注意事项
以上是Go的非阻塞TCP读取中如何处理数据接收不完整的情况?的详细内容。更多信息请关注PHP中文网其他相关文章!