重用 TcpClient 和 NetworkStream 导致数据错误

Reusing TcpClient and NetworkStream results in wrong data

我正在 WPF 上编写屏幕镜像应用程序。我的原始代码通过 TCP 从服务器向客户端发送位图。原始代码工作正常,但每次发送帧时都会关闭并重新创建 tcp 连接。这导致每秒打开和关闭 30 个套接字,我认为这不是理想的方法。

所以我试图重写它以在每次发送数据时重用流,但是流过一段时间后开始吐出错误的数据。

public void SendStream(byte[] byteArray)
{
    /*
    _client = IsServer ? _server.AcceptTcpClient() : new TcpClient(IP.ToString(), Port);
    using (var clientStream = _client.GetStream())
    {
        var comp = Compress(byteArray);
        clientStream.Write(comp, 0, comp.Length);
    }
    */

    var comp = Compress(byteArray);
    _stream.Write(BitConverter.GetBytes(comp.Length), 0, 4);
    _stream.Write(comp, 0, comp.Length);
}

public byte[] ReceiveStream()
{
    /*
    _client = IsServer ? _server.AcceptTcpClient() : new TcpClient(IP.ToString(), Port);
    var stream = _client.GetStream();
    return Decompress(stream);
    */

    var lengthByte = new byte[4];
    _stream.Read(lengthByte, 0, 4);
    var length = BitConverter.ToInt32(lengthByte, 0);
    var data = new byte[length];
    _stream.Read(data, 0, length);
    return Decompress(new MemoryStream(data));
}

压缩和解压缩功能只是对内置 DeflateStream 的包装。

我检查了错误发生时发送的comp.Length和接收的length是一样的。

有什么想法吗?谢谢。它总是在至少几帧之后抛出异常,而不是第一帧(至少我到目前为止已经尝试过)

(当位图尺寸较大时似乎发生得更快,即当压缩算法不那么多时导致屏幕更复杂。虽然不是 100% 确定)

尝试执行以下操作:

    int receivedBytesCount = _stream.Read(data, 0, length);

您传递给 Read 方法的长度变量是最大值。 Read 方法实际读取的字节数可能少于长度。它将 return 它实际读取的字节数。当您的数据被分割成 TCP 数据包时,就会发生这种情况。 您需要继续调用 Read 直到收到足够的字节并将所有内容组合起来以获得完整的帧。您将需要调整偏移量以避免覆盖缓冲区。在您发布的代码中,它被硬编码为 0。