首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在不预先指定字节片长度的情况下,使用net.TCPConn在golang中读取?

如何在不预先指定字节片长度的情况下,使用net.TCPConn在golang中读取?
EN

Stack Overflow用户
提问于 2014-07-03 16:04:09
回答 2查看 1.1K关注 0票数 0

我试图从与redis客户端的tcp连接(一个正在运行redis-cli的终端)中读取一些消息。但是,net包的朗读命令要求我提供一个片段作为参数。每当我给一个没有长度的切片时,连接就会崩溃,围棋程序就会停止。我不知道我的字节消息需要多少长度。因此,除非我指定了一些大得离谱的片段,否则这个连接将始终关闭,尽管这似乎是浪费。我想知道,不需要事先知道消息的长度,就能保持联系吗?我很想解决我的具体问题,但我觉得这个问题比较笼统。为什么我要知道手边的长度?图书馆就不能给我一片合适的尺寸吗?

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-03 16:45:01

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

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

打电话给Read并不能保证给你带来你所期望的一切。它可能返回的较少,它可能返回更多,这取决于您已经收到的数据。做IO的库通常通过一个“缓冲区”进行读写;您将拥有"read“,这是一个预先分配的字节段(最多32k是常见的),并且您每次想从网络中读取时都重复使用该块。这就是IO函数返回字节数的原因,因此您知道上次操作填充了多少缓冲区。如果缓冲区已被填充,或者仍然需要更多数据,则只需再次调用Read即可。

票数 6
EN

Stack Overflow用户

发布于 2021-05-08 17:58:51

有点晚了但是..。

  1. 问题之一是如何确定消息大小。JimB给出的答案是,TCP是一个流协议,所以没有真正的目的。
  2. 我相信这个答案是不正确的。TCP将比特流分成顺序分组。每个数据包都有一个IP报头和一个TCP报头(参见维基百科这里 )。每个数据包的IP报头包含该数据包长度的字段。为了得到实际的数据长度,您必须做一些数学运算才能减去TCP头长度。此外,可以在TCP报头中指定消息的最大长度。
  3. 因此,您可以为读取操作提供足够长度的缓冲区。但是,您必须首先读取数据包报头信息。如果最大消息大小比您愿意接受的长度长,您可能不应该接受TCP连接。
  4. 通常,发送方将终止与fin数据包的连接(请参阅1),而不是EOF字符。
  5. 读取操作中的EOF最有可能表示没有在分配的时间内完全传输包。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24558535

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档