【问题标题】:C# Networkstream BeginRead How to obtain buffer length/size?C# Networkstream BeginRead 如何获取缓冲区长度/大小?
【发布时间】:2014-10-30 10:00:37
【问题描述】:

我在获取应用程序的正确缓冲区大小时遇到​​问题。 我从网站上读到的关于指定缓冲区大小的内容通常在阅读之前声明。

byte[] buffer = new byte[2000];

然后使用得到结果。 但是,一旦接收到的数据包含'00',此方法将停止,但我的返回代码包含类似这样的内容...... 5300000002000000EF0000000A00。而且长度不固定,可以这么短到400字节

所以问题来了,如果我像上面定义一个前缀长度,例如 2000,返回值是 5300000002000000EF0000000A000000000000000000000000000000000000000000000000000....... 从而使我无法将字节拆分为正确的数量。

any1 可以告诉我如何从网络流中获取实际接收到的数据大小或任何方法/作弊来获得我需要的东西吗?

提前致谢。

【问题讨论】:

  • 向我们展示你拥有的东西。
  • 基本上我无法在这里显示任何内容,因为我被卡住了,根本无法继续。我写的唯一与这个主题相关的东西是tcpstream.BeginRead(readbuffer, 0, (int)tcpsocket.ReceiveBufferSize, new AsyncCallback(ReceiveCallBack), tcpstream);,我被困在 ReceiveCallBack 方法中,因为完全无法处理传入的数据
  • NetworkStream 继承 Stream,所以Stream.Length 将包含流的长度(如果已知)。
  • 这个已经试过了。它返回 seek is not supported

标签: c# networkstream


【解决方案1】:

网络流没有长度。

很遗憾,您的问题很详细,因此很难提供具体建议。但您有两种选择:

  • 如果这里使用的高级协议提供了一种了解将要发送的数据长度的方法,请使用它。这可以像远程主机在其余数据之前发送字节数一样简单,或者您可以向远程主机发送一些命令以查询数据的长度。在不知道您使用的高级协议的情况下,无法说这是否是一种选择。

  • 将传入数据写入 MemoryStream 对象。这将始终有效,无论高级协议是否提供了一种提前了解预期数据量的方法。请注意,如果没有,那么您只需接收数据,直到网络流结束。

后一个选项看起来像这样:

MemoryStream outputStream = new MemoryStream();
int readByteCount;
byte[] rgb = new byte[1024]; // can be any size

while ((readByteCount = inputStream.Read(rgb, 0, rgb.Length)) > 0)
{
    outputStream.Write(rgb, 0, readByteCount);
}

return outputStream.ToArray();

这假设您有一个名为“inputStream”的网络流。

我展示上面的内容主要是因为它说明了从网络流中分段读取然后将结果存储在其他地方的更一般的做法。此外,它很容易适应直接从套接字实例读取(您没有提到您实际用于网络 I/O 的内容)。

但是,如果您实际使用 Stream 对象进行网络 I/O,那么从 .NET 4.0 开始,有一种更方便的方式来编写上述内容:

MemoryStream outputStream = new MemoryStream();

inputStream.CopyTo(outputStream);

return outputStream.ToArray();

【讨论】:

  • 非常感谢您的解释和回答。它适用于我的程序。并且需要在while循环中添加break;,否则它将是无限的。由于与其他硬件的兼容性,我的程序在 .net framework 3.5 中运行,因此无法测试更简单的代码。
  • 无限循环很奇怪。您使用什么条件来控制break 语句的执行?最好将这些信息合并到更高级别,具体取决于它是什么。
  • 我使用的代码和你写的一样,尤其是获取传入数据数量的部分。由于您输入了while(... > 0),如果 inputStream.Read 包含数据,它将>0,因此它将永远停留在 while 循环中。所以添加break;会在获取数据后退出while循环。
  • 抱歉,你说的不通。如果您在代码中添加了break 语句,那么您就没有使用“就像您 [I] 写的那样”的代码。 > 0 的测试是该代码的一个关键元素,因为您希望只要读取了数据就继续循环。请重新阅读我的回答,尤其是我指出我提供的两个广泛建议中的一个或另一个但不是两者都合适的部分。
猜你喜欢
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 1970-01-01
  • 2021-04-26
  • 1970-01-01
  • 2011-05-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多