简体   繁体   English

c#socket接收字节数组长度

[英]c# socket receive byte array length

i'm trying to learn to use sockets in c# and i've a doubt, i'm using a code something like this: 我正在尝试学习在c#中使用套接字,我有一个疑问,我正在使用这样的代码:

byte[] data = new byte[64]; 
int length = 0;
length = sock.Receive(data);
//more code...

So, the byte[] data is filled with the recived data and the left space in the array is filled with 0s, Is the byte[] allocated into memory completely (all 64bytes)? 因此, byte[]数据填充了被回收的数据,并且数组中的左侧空格填充为0, byte[]是否完全分配到内存中(全部为64字节)? If it's so, is there a way to make the byte[] the same size as the actual sent data? 如果是这样,有没有办法使byte[]与实际发送的数据大小相同?

You can check sock.Available to see what has already come in. (so far) 你可以检查sock.Available看看已经进来的东西。(到目前为止)

byte[] data = new byte[sock.Available]; 
int length = sock.Receive(data);
//more code...

Note: Since you may or may not know what is coming in next on the network it usually makes more sense to read only a header (with size info) first or to allocate more space than necessary, and call .Recieve() multiple times until the end of a record is reached. 注意:由于您可能知道或者可能不知道网络上接下来会发生什么,因此通常首先只读取标题(带有大小信息)或者分配比所需更多的空间更有意义,并多次调用.Recieve()直到到达记录的结尾。

Note: This code assumes you already know there is some data to receive and you've waited long enough for some useful amount of data to be ready. 注意:此代码假设您已经知道有一些数据要接收,并且您已经等待足够长的时间来准备好一些有用的数据。

If you do choose to use length headers, .Available can help you avoid reading a partial header and having to re-assemble it which is nice. 如果你确实选择使用长度标题, .Available可以帮助你避免阅读部分标题并且必须重新组合它,这很好。 (Only large messages may need manual reassembly in that case) (在这种情况下,只有大型消息可能需要手动重组)

As noted normally read may return fewer bytes then it was told. 如前所述,通常读取可能会返回更少的字节然后被告知。 See a workaround function below which ensures it reads as many bytes as it was told - basically size of the passed buffer. 请参阅下面的解决方法函数,该函数确保它读取的字节数与告知的一样多 - 基本上是传递缓冲区的大小。 Function is from here . 功能来自这里

/// 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;
    }
}

You can use this method first to read say a 2 byte integer which should represent the number of bytes that will follow. 您可以首先使用此方法来读取2字节整数 ,该整数应表示将遵循的字节数。 Then you read once again however now read as many bytes as specified in that two byte integer. 然后再次读取,但现在读取的字节数与该两个字节整数中指定的字节数相同。

But for this to work, clearly the sender first has to send a two byte integer which represents length of data that will follow - and then the data itself. 但为了实现这一点,显然发送方首先必须发送一个两字节整数,表示将跟随的数据长度 - 然后是数据本身。

So basically you call above function on a byte array of size two first (to get data length), and then on a byte array with size as indicated in that 2 byte integer (to get data). 所以基本上你首先在大小为2的字节数组上调用上面的函数(以获得数据长度),然后在一个字节数组上调用大小,如2字节整数所示(以获取数据)。

You can use this to read from NetworkStream . 您可以使用它来从NetworkStream读取。 Some more reading on this topic. 关于这个主题的更多阅读

You simply need to use the return value from Receive to understand how much data has arrived. 您只需使用Receive的返回值来了解已到达的数据量。 You can shorten the buffer using Array.Resize if you want but that normally would be a sign that something is wrong. 如果需要,可以使用Array.Resize缩短缓冲区,但这通常表示出现问题。

Also note, that TCP is a stream of bytes and does not preserve message boundaries. 另请注意,TCP是一个字节流,不保留消息边界。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM