重用 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。
我正在 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。