golang中的net.TCPConn不事先指定字节切片的长度,如何读取?

Cha*_*ker -1 tcp go

我试图从与 redis 客户端(仅运行 redis-cli 的终端)的 tcp 连接读取一些消息。但是,net 包的Read命令要求我提供一个切片作为参数。每当我给出一个没有长度的切片时,连接就会崩溃并且 go 程序停止。我不确定我的字节消息需要多长。因此,除非我指定某个大得离谱的切片,否则此连接将始终关闭,尽管这看起来很浪费。我想知道,是否可以保持连接而不必事先知道消息的长度?我很想解决我的具体问题,但我觉得这个问题更笼统。为什么我需要事先知道长度?图书馆不能给我一份正确大小的切片吗?

或者人们建议什么其他解决方案?

Jim*_*imB 5

不知道消息大小正是您必须指定读取大小的原因(这适用于任何网络库,而不仅仅是 Go)。TCP 是一种流协议。就 TCP 协议而言,消息一直持续到连接关闭。

如果您知道要读到 EOF,请使用 ioutil.ReadAll

电话Read并不能保证让您得到您所期望的一切。它可能返回更少,也可能返回更多,具体取决于您收到的数据量。执行 IO 的库通常通过“缓冲区”进行读写;你会有你的“读取缓冲区”,它是一个预先分配的字节切片(最多 32k 是常见的),并且每次想要从网络读取时都重新使用该切片。这就是 IO 函数返回字节数的原因,因此您知道上次操作填充了多少缓冲区。如果缓冲区已满,或者您仍然期待更多数据,则只需Read再次调用即可。

  • EOF 不是消息的结束,而是连接被关闭。TCP 不仅用于发送单个数据块,它还是一个可用于发送和接收消息的流。网络连接甚至不知道“消息”是什么,这取决于应用程序来确定数据是如何构成的。 (2认同)
  • @Pinocchio,这就是为什么使用 [`Type-Length-Value` 方案](http://en.wikipedia.org/wiki/Type-length-value) 经常用于实现使用流的应用程序级协议的原因-基于 TCP 的协议。 (2认同)