Go TCP 读取是非阻塞的

2024-04-24

我正在尝试用 Go 创建服务器和客户端,我已经成功地与服务器和客户端进行通信。但我遇到的问题是golang中的TCP读取是非阻塞的。 我想知道 golang 中的读取是否有可能像 C 中的读取一样阻塞。 谢谢

EDIT:

这是服务器的源代码:

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"))
}

Readers 可以返回部分数据。从the docs http://golang.org/pkg/io/#Reader,“如果某些数据可用,但不是 len(p) 字节,则读取通常会返回可用数据,而不是等待更多数据。”

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

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

示例代码有一个可能不相关但很重要的问题:它从Read and Write。这可能会掩盖简单的问题并使它们很难调试。如果您在考虑部分读取后遇到问题,请在寻求更多帮助之前检查所有错误。看着errcheck https://github.com/kisielk/errcheck/确保这样的错误不会出现在生产中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go TCP 读取是非阻塞的 的相关文章

随机推荐