c# - 通过 TCP 接收数据:MemoryStream 包含比预期更多的数据
问题描述
我托管了一个服务器,它从远程 TCP 客户端(我也控制它)接收数据。这是处理传入数据的方法:
private static async Task ReceiveDataFromRemoteSocket(
Socket socket,
int numBytesExpectedToReceive)
{
int numBytesLeftToReceive = numBytesExpectedToReceive;
using (MemoryStream memoryStream = new MemoryStream(numBytesExpectedToReceive))
{
byte[] dataBuffer = new byte[1024];
ArraySegment<byte> dataBufferSegment = new ArraySegment<byte>(dataBuffer);
int totalBytesReceived = 0;
while (numBytesLeftToReceive > 0)
{
Array.Clear(dataBuffer, 0, dataBuffer.Length);
int numBytesReceived = await socket.ReceiveAsync(dataBufferSegment, SocketFlags.Partial);
Console.WriteLine($"Received {numBytesReceived} bytes of data at {DateTime.UtcNow.ToShortTimeString()}.");
totalBytesReceived += numBytesReceived;
memoryStream.Write(
dataBuffer,
0,
numBytesLeftToReceive < dataBuffer.Length ? numBytesLeftToReceive : dataBuffer.Length);
numBytesLeftToReceive -= numBytesReceived;
}
Console.WriteLine($"Total number of bytes received, according to tally: {totalBytesReceived}.");
Console.WriteLine($"Memory stream: Contains {memoryStream.Length} bytes' worth of data.");
}
}
numBytesExpectedToReceive
是从标头中检索的信息。
这是我控制台上的输出:
已于 2019 年 4 月 30 日上午 10:39:11 接受来自 XX.XX.XXX.XXX:56767 的连接请求。
期望从 XX.XX.XXX.XXX:56767 接收 41898 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 416 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 96 个字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 1024 字节的数据。
上午 10:39 收到 512 字节的数据。
接收到的字节总数,根据计数:41984。
内存流:包含 43434 字节的数据。
如您所见,内存流包含 43434 字节的数据,尽管我希望它只包含 41984 字节。
这会导致很多问题,例如,如果我ZipArchive
通过编写创建一个新实例new ZipArchive(memoryStream);
,我最终会得到一个InvalidDataException
,即使我知道我的远程 TCP 客户端已经发送了一个有效的 zip 文件。
- 为什么内存流包含的字节数比通过 TCP 实际接收的要多?
- 如何删除这些“垃圾数据”(因为没有更好的术语),以便我可以成功地重建发送给我的数据,例如通过将内存流传递给
ZipArchive
构造函数?
解决方案
问题出在你写数据的地方:
memoryStream.Write(
dataBuffer,
0,
numBytesLeftToReceive < dataBuffer.Length ? numBytesLeftToReceive : dataBuffer.Length);
您完全忽略了收到的数量,而是检查是否有比自助餐大小更多的数据要接收,以及是否有您写入整个缓冲区。
您可以在输出中看到有时您没有收到完整的缓冲区。然而你仍然写了整个缓冲区。
始终根据您收到的金额来写。不要根据数据的长度做任何奇怪的比较:
memoryStream.Write(
dataBuffer,
0,
numBytesReceived);
推荐阅读
- python - 如何在 django 中按类别过滤
- android-studio - Android Studio 突出显示代码红色且没有错误(Gradle 4.0.0 错误)
- excel - 尝试从 Excel 中的 Google 表格复制“IMAGE()”函数
- php - 试图获取非对象的属性 [LARAVEL]
- java - 如何按降序对 TreeMap 值进行排序以及如何限制输出?
- sql - Oracle SQL XML 提取
- google-cloud-storage - 如何在批量存储 json api 中使用 rewriteToken?
- react-spring - react-use-gesture + spring - 从手势识别中排除嵌套元素
- python - 用于小型计算的 Python 可扩展并行处理
- javascript - TypeScript 编译器是否存在关于泛型的错误,或者我遗漏了什么?