Go TCP读取是非阻塞的

我想在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可以返回部分数据。 从文档中可以看出 ,“如果某些数据可用但不是len(p)字节,则Read会按常规返回可用内容,而不是等待更多内容。”

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

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

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