gpt4 book ai didi

c - Go TCP 读取是非阻塞的

转载 作者:IT王子 更新时间:2023-10-29 01:09:58 29 4
gpt4 key购买 nike

我正在尝试用 Go 制作服务器和客户端,我已经设法与服务器和客户端进行通信。但是我遇到的问题是在golang中读取的TCP是非阻塞的。我想知道 golang 中的读取是否有可能像 C 中的读取那样被阻塞。谢谢你

编辑:

服务器源代码如下:

func Init_tcp() *net.TCPListener {
laddr, err := net.ResolveTCPAddr("tcp", ":4243")
if err != nil {
log.Fatal(err)
}
tcp, err := net.ListenTCP("tcp", laddr)
if err != nil {
log.Fatal(err)
}
return tcp
}

func main() {
tcp := Init_tcp()
conn, _ := tcp.Accept()
data := make([]byte, 512)
conn.SetNoDelay(false)
for {
conn.Read(data)
fmt.Println(data)
}
}

和我的客户:

func Init_tcp() *net.TCPConn {
laddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:4243")
if err != nil {
log.Fatal(err)
}
tcp, err := net.DialTCP("tcp", nil, laddr)
if err != nil {
log.Fatal(err)
}
return tcp
}

func main() {
tcp := Init_tcp()
tcp.Write([]byte("hello world"))
}

最佳答案

Reader 可以返回部分数据。来自 the docs , "如果一些数据可用但不是 len(p) 字节,Read 通常会返回可用的数据而不是等待更多数据。"

这在任何语言中都是一个问题,即使这样的事情碰巧在 C 中为您工作:TCP 只是提供了一个可以随时写入的字节流。根据设计,单次写入可能会被分成多个数据包进行传输,并且没有内置信号通知接收方说明单次写入/消息/请求结束的位置。应用程序必须找出自己的方式来发出边界信号。这可能意味着分隔符 (\n) 或隐式或显式字节计数(HTTP 的 Content-Length 是显式的)。

要读取特定数量的输入字节,您需要 io.ReadAtLeastio.ReadFull。要读取直到满足某个任意条件,只要没有错误,您应该只循环调用 Read 。 (然后你可能想在输入太大时出错,以防止坏客户端吃掉服务器资源。)如果你正在实现基于文本的协议(protocol),你应该考虑 net/textproto , 它放了一个 bufio.Reader在连接前面,这样你就可以阅读线路。要限制您等待完成阅读的时间(这样一个行为不端的客户端不能让 goroutine 挂起并永远使用内存等),请查看 net名称中带有 Deadline 的函数(与 Error 类型的 Timeout 函数相关)。 context包有助于管理超时、截止日期和取消,例如,如果您正在编写一个复杂的服务器,该服务器将在每个请求中执行许多网络操作,则该包特别有用。

示例代码有一个可能不相关但很重要的问题:它丢弃了来自ReadWrite 的错误。这可能会掩盖简单的问题并使它们很难调试。如果您在考虑部分读取后遇到问题,请在寻求更多帮助之前检查所有错误。看errcheck确保这样的错误不会进入生产。

关于c - Go TCP 读取是非阻塞的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26999615/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com