一尘不染

去TCP读取是非阻塞的

go

我正在尝试在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"))
}

阅读 184

收藏
2020-07-02

共1个答案

一尘不染

Reader可以返回部分数据。从该文档,“如果某些数据是可用的,但不是LEN(P)个字节,读取常规返回什么是可用的,而不是等待更多。”

无论使用哪种语言,这都是一个问题,即使在C语言中碰巧对您有用:TCP只是提供了可以随时写入的字节流。从设计上讲,单次写入可能会分解为多个数据包进行传输,并且没有向接收方发送的内置信号说明单次写入/消息/请求在何处结束。该应用程序必须找出自己的信号边界方法。这可能意味着定界符(\n)或隐式或显式的字节计数(HTTP
Content-Length是显式的)。

要读取特定数量的输入字节,您需要io.ReadAtLeastio.ReadFull。要读取直到满足某些任意条件Read,只要没有错误,就应该在调用上循环。(然后,您可能想对太大的输入进行错误处理,以防止不良的客户端占用服务器资源。)如果要实现基于文本的协议,则应考虑使用net/textproto,它会将a
bufio.Reader放在连接的前面,以便您可以读行。要限制您等待多长时间才能完成读取(以使行为不正常的客户端无法永远挂断goroutine并永远使用内存等),请查看名称中的net函数Deadline(与上的Timeout函数相关)Error类型)。的context
软件包可帮助管理超时,期限和取消,并且在例如要编写一台复杂的服务器来对每个请求执行许多网络操作的情况下特别有用。

该示例代码可能存在不相关但很重要的问题:它丢弃了Readand中的错误Write。这可能掩盖了简单的问题,并使它们很难调试。如果考虑了部分读取后仍遇到问题,请先检查所有错误,然后再寻求更多帮助。查看errcheck以确保不会将此类错误付诸实践。

2020-07-02