write()和read()raw字节来自NetworkStream,数据在某些字节上是差异



我已经编写了一些代码,用于在发送之前使用已知大小的NetworkStream发送byte []数组,但是发送的数据和收到的数据在某些位置是差异。

maxsize是我要发送的数据的已知大小。

    public static void SendBytes(TcpClient clientSocket, byte[] outStream)
    {
        Debug.WriteLine("SendBytes() number of bytes: " + outStream.Length.ToString());
        NetworkStream serverStream = clientSocket.GetStream();
        serverStream.Write(outStream, 0, outStream.Length);
        //serverStream.Flush();
    }
    public static byte[] ReceiveBytes(TcpClient clientSocket, int MAX_SIZE)
    {
        Debug.WriteLine("[" + DateTime.Now.ToString("G") + "] - " + "ReceiveBytes() started.");
        NetworkStream networkStream = clientSocket.GetStream();
        byte[] bytesFrom = new byte[MAX_SIZE];
        clientSocket.ReceiveBufferSize = MAX_SIZE;
        networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
        Debug.WriteLine("[" + DateTime.Now.ToString("G") + "] - " + "ReceiveBytes(), received number of raw bytes: " + bytesFrom.Length.ToString());
        return CommonUtils.SubArray(bytesFrom, 0, MAX_SIZE);
    }

如果发送数据(十六进制中的字节(:A7 FC D0 51 0E 99 CF 0D 00,收到的数据是:A7 FC D0 51 0E 99 CF 0d 53

很可能是由于数据包结构而看到的垃圾;TCP仅保证正确的字节将以正确的顺序(或流故障(到达 - 它对它们到达的没有说明。因此,您是 cavital 您:

  1. Read捕获返回值,只有从任何块中的许多字节
  2. 执行您自己的框架 - 即独立于零件到达的方式将流批准为消息

如果您的消息始终是固定大小,则" 2"将变为"缓冲区数据,直到我至少具有n个字节为止,然后在n块中处理数据,保留剩下的所有内容,然后恢复缓冲"。但是在一般情况下,它可能是"缓冲区,直到我看到哨兵值,例如线馈线",或"缓冲区",直到我拥有完整的标头,然后解析标头以查看要期望的数据,然后才直到我有很多数据"。

有一些工具和实用程序可以帮助使框架和处理积压更简单 - 例如,使用新的"管道" API,这只是检查管道并告诉管道要消耗多少的情况(而不是为您提供一切,而您目前无法拒绝数据( - 但是,从Stream转换为"管道"对大多数人来说是很多更改。

在您的情况下,您可能可以使用:

byte[] bytesFrom = new byte[MAX_SIZE];
int outstanding = MAX_SIZE, read, offset = 0;
while (outstanding > 0 && (read = networkStream.Read(bytesFrom, offset, outstanding)) > 0)
{
    offset += read;
    outstanding -= read;
}
if (outstanding != 0) throw new EndOfStreamException();

这会创建一个读取循环,该循环完全填充bytesFrom,或者在例外失败。

Stream.Read返回一个值,该值指示实际 read。它绝不保证与您要求的金额相同。在您的危险中忽略这个值。

如果您很乐意为整个流分配内存,为什么不将其复制到MemoryStream中并从中钓鱼完全缓冲呢? Stream.CopyToStream.CopyToAsync是一个不错的高级抽象,使它变得容易。

最新更新