[英]c# socket receive byte array length
我正在尝试学习在c#中使用套接字,我有一个疑问,我正在使用这样的代码:
byte[] data = new byte[64];
int length = 0;
length = sock.Receive(data);
//more code...
因此, byte[]
数据填充了被回收的数据,并且数组中的左侧空格填充为0, byte[]
是否完全分配到内存中(全部为64字节)? 如果是这样,有没有办法使byte[]
与实际发送的数据大小相同?
你可以检查sock.Available
看看已经进来的东西。(到目前为止)
byte[] data = new byte[sock.Available];
int length = sock.Receive(data);
//more code...
注意:由于您可能知道或者可能不知道网络上接下来会发生什么,因此通常首先只读取标题(带有大小信息)或者分配比所需更多的空间更有意义,并多次调用.Recieve()
直到到达记录的结尾。
注意:此代码假设您已经知道有一些数据要接收,并且您已经等待足够长的时间来准备好一些有用的数据。
如果你确实选择使用长度标题, .Available
可以帮助你避免阅读部分标题并且必须重新组合它,这很好。 (在这种情况下,只有大型消息可能需要手动重组)
如前所述,通常读取可能会返回更少的字节然后被告知。 请参阅下面的解决方法函数,该函数确保它读取的字节数与告知的一样多 - 基本上是传递缓冲区的大小。 功能来自这里 。
/// Reads data into a complete array, throwing an EndOfStreamException
/// if the stream runs out of data first, or if an IOException
/// naturally occurs.
/// </summary>
/// <param name="stream">The stream to read data from</param>
/// <param name="data">The array to read bytes into. The array
/// will be completely filled from the stream, so an appropriate
/// size must be given.</param>
public static void ReadWholeArray (Stream stream, byte[] data)
{
int offset=0;
int remaining = data.Length;
while (remaining > 0)
{
int read = stream.Read(data, offset, remaining);
if (read <= 0)
throw new EndOfStreamException
(String.Format("End of stream reached with {0} bytes left to read", remaining));
remaining -= read;
offset += read;
}
}
您可以首先使用此方法来读取2字节整数 ,该整数应表示将遵循的字节数。 然后再次读取,但现在读取的字节数与该两个字节整数中指定的字节数相同。
但为了实现这一点,显然发送方首先必须发送一个两字节整数,表示将跟随的数据长度 - 然后是数据本身。
所以基本上你首先在大小为2的字节数组上调用上面的函数(以获得数据长度),然后在一个字节数组上调用大小,如2字节整数所示(以获取数据)。
您可以使用它来从NetworkStream
读取。 关于这个主题的更多阅读 。
您只需使用Receive
的返回值来了解已到达的数据量。 如果需要,可以使用Array.Resize
缩短缓冲区,但这通常表示出现问题。
另请注意,TCP是一个字节流,不保留消息边界。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.