【问题标题】:How to know that the stream has ended C#如何知道流已经结束 C#
【发布时间】:2012-03-17 04:55:48
【问题描述】:

我正在尝试在 C# 中接收 tcp 数据包,但我不知道何时可以停止从流中读取。 这是我尝试过的:

for(int i = 0; i < stm.Length; i += chunkSize)
{
    bb = new byte[chunkSize];
    k = stm.Read(bb, 0, bb.Length);
    ns.Write(bb, 0, k);
}

但它给我带来了一个错误,即流不可搜索。 所以我试过这个:

int k = chunkSize;

while (k == chunkSize)
{
    bb = new byte[chunkSize];
    k = stm.Read(bb, 0, bb.Length);
    ns.Write(bb, 0, k);
}

有什么可做的吗? 谢谢:)

【问题讨论】:

  • 你为什么不谷歌“如何从 C# 中的 TCP-Stream 读取”?必须有 1000ds 的解释可用。
  • 我相信设置 k 等于 chunkSize 可能会有问题。看看 stream.Read() 返回什么。它并不总是符合您的预期。

标签: c# stream


【解决方案1】:

我们开始吧:

int read;
while((read = stm.Read(bb, 0, bb.Length)) > 0) {
    // process "read"-many bytes from bb
    ns.Write(bb, 0, read);
}

“read”在流结束时为非正数,并且仅在流结束时。

或更简单地说(在 4.0 中):

stm.CopyTo(ns);

【讨论】:

  • 问题在于,如果没有可读取的内容,代码会冻结在 Read 方法上。我猜有超时之类的东西,但我认为等待超时不是正确的解决方案每个数据包的结尾
  • @JohnSmith 然后你会想要使用类似 Select() 来确定是否有数据可供读取。
  • @John 是的,您刚刚完美地描述了 Read 的行为。如果您不希望这样,您将不得不使用其中一个异步 API,并且有时在发送套接字上禁用“nagle”
  • @JohnSmith,如果您担心同步读取 - 请改用异步版本 - 查看涵盖 BeginRead 和相关方法的 msdn.microsoft.com/en-us/magazine/cc337900.aspx
【解决方案2】:

二进制阅读器是您所需要的,因为它确切地知道要读取多少字节!

它以字节长度为前缀,因此它知道要读取多少!

【讨论】:

  • 二进制阅读器仅在一些非常特定的场景中执行此操作,如果协议在其他地方定义,则根本没有用。坦率地说,我做了很多通讯/协议/序列化/等代码,我从来没有使用过 BinaryReader。
  • 哈哈哈......我知道我错了......谢谢你的信息......但是阅读字符串没有帮助......
  • 我没有说“错”——也许只是……过于热情。使用字符串:同样,这是否有用完全取决于有线协议如何表示它们是存储的。例如,本周我一直在编写 WebSocket 成帧器; (基本上)有 2 个 WebSocket 协议,并且都处理字符串 - 这对它们中的任何一个都没有帮助。它对 redis 协议或 protobuf 协议等中的字符串也无济于事......
猜你喜欢
  • 1970-01-01
  • 2020-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多