c#socket接收字节数组长度

时间:2015-12-15 18:55:50

标签: c# bytearray

我试图学习在c#中使用套接字而且我有疑问,我使用的代码是这样的:

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

因此,byte[]数据填充了重新获取的数据,数组中的左侧空格填充为0,byte[]是否已完全分配到内存中(全部为64字节)?如果是这样,有没有办法让byte[]与实际发送的数据大小相同?

3 个答案:

答案 0 :(得分:3)

您可以查看sock.Available以查看已经发生的事情。(到目前为止)

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

注意:由于您可能知道或者可能不知道网络上接下来会发生什么,因此通常首先只读取标题(带有大小信息)或者分配比所需更多的空间更有意义,并调用{{1}多次,直到达到记录结束。

注意:此代码假设您已经知道有一些数据需要接收,并且您已经等待了足够长的时间来准备好一些有用的数据。

如果您确实选择使用长度标题,.Recieve()可以帮助您避免阅读部分标题并且必须重新组合它,这很好。 (在这种情况下,只有大型消息可能需要手动重组)

答案 1 :(得分:2)

如前所述,通常读取可能会返回更少的字节然后被告知。请参阅下面的解决方法函数,该函数确保它读取的字节数与告知的一样多 - 基本上是传递缓冲区的大小。功能来自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;
    }
}

您可以先使用此方法来读取一个2字节整数,它应该代表将遵循的字节数。然后你再次阅读,但现在读取那个字节数,就像那个两个字节的整数一样。

但为了实现这一点,显然发送方首先必须发送一个两字节的整数,表示将跟随的数据长度 - 然后是数据本身。

所以基本上你首先在大小为2的字节数组上调用上面的函数(以获得数据长度),然后在字节数组上调用大小,如2字节整数所示(以获取数据)。

您可以使用它来阅读NetworkStream。关于此主题还有一些reading

答案 2 :(得分:1)

您只需使用Sub RunMc() Dim a(1 To 2) As String Dim MN As String For i = 1 To 2 'Fill the array a(i) = "m" & i Next MN = "Module1" 'the module name For i = LBound(a) To UBound(a) Application.Run MN & "." & a(i) Next End Sub Sub m1() Debug.Print "m1" End Sub Sub m2() Debug.Print "m2" End Sub 的返回值即可了解已到达的数据量。如果需要,可以使用Receive缩短缓冲区,但这通常表示出现问题。

另请注意,TCP是一个字节流,不保留消息边界。