简体   繁体   English

去TCP读取是非阻塞的

[英]Go TCP read is non blocking

I am trying to make a server and client in Go, I have managed to communicate with the server and client. 我正在尝试在Go中创建服务器和客户端,我已经设法与服务器和客户端进行通信。 But the problem I have is that the TCP read in golang is non-blocking. 但是我的问题是,在golang中读取的TCP是非阻塞的。 What I would like to know if is it possible for the read in golang to be blocking like read in C. Thank You 我想知道的是,golang中的读取是否可能像C中的读取一样被阻塞。谢谢

EDIT: 编辑:

Here is the source code of the server: 这是服务器的源代码:

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

and my client: 和我的客户:

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 s can return partial data. Reader可以返回部分数据。 From the docs , "If some data is available but not len(p) bytes, Read conventionally returns what is available instead of waiting for more." 在文档中 ,“如果某些数据可用,但不是len(p)个字节,按常规,Read将返回可用数据,而不是等待更多数据。”

This is an issue in any language, even if something like this happened to work for you in C: TCP just provides a stream of bytes that can be written to any time. 无论使用哪种语言,这都是一个问题,即使在C语言中这种情况对您来说也是如此:TCP只是提供了可以随时写入的字节流。 Single writes might, by design, be broken up into multiple packets for transmission, and there's no built-in signal to the receiver saying where a single write/message/request ends. 从设计上讲,单次写入可能会分解为多个数据包进行传输,并且没有内置的信号向接收方说明单次写入/消息/请求在何处结束。 The application has to figure out its own way to signal boundaries. 应用程序必须找出自己的信号边界方法。 That can mean delimiters ( \\n ) or implicit or explicit byte counts (HTTP's Content-Length is an explicit one). 这可能意味着定界符( \\n )或隐式或显式的字节数(HTTP的Content-Length是显式的)。

To read a specific number of input bytes, you want io.ReadAtLeast or io.ReadFull . 要读取特定数量的输入字节,您需要io.ReadAtLeastio.ReadFull To read until some arbitrary condition is met you should just loop on the Read call as long as there is no error. 要读取直到满足某些任意条件,只要没有错误,就应该在Read调用上循环。 (Then you may want to error out on on too-large inputs to prevent a bad client from eating server resources.) If you're implementing a text-based protocol you should consider net/textproto , which puts a bufio.Reader in front of the connection so you can read lines. (然后,您可能想对太大的输入进行错误处理,以防止不良的客户端net/textproto服务器资源。)如果要实现基于文本的协议,则应考虑使用net/textproto ,它将bufio.Reader放在前面连接,以便您可以阅读线路。 To limit how long you'll wait to finish reading (so that a misbehaving client can't leave a goroutine hanging and using memory, etc. forever), look at the net functions with Deadline in the name (which are related to the Timeout functions on the Error types). 为了限制您等待多长时间才能完成读取(以使行为异常的客户端无法永远挂断goroutine并永远使用内存等),请查看名称中带有Deadlinenet函数(与Timeout相关) Error类型)。 The context package helps manage timeouts, deadlines, and cancellation, and is especially useful if, for example, you're writing a complex server that's going to do many network operations every request. context包有助于管理超时,期限和取消,并且在例如您要编写一个复杂的服务器来对每个请求执行许多网络操作的情况下特别有用。

The sample code has a possibly unrelated but important problem: it throws away errors from the Read and Write . 示例代码有一个可能不相关但重要的问题:它丢弃了ReadWrite错误。 That could mask simple problems and make them very hard to debug. 这可能掩盖了简单的问题,并使它们很难调试。 If you have problems after accounting for partial reads, check all errors before asking for more help. 如果考虑了部分读取后仍遇到问题,请先检查所有错误,然后再寻求更多帮助。 Look at errcheck to make sure mistakes like this don't get into production. 查看errcheck ,以确保不会发生类似这样的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM