我托管一台服务器,该服务器从远程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日接受了来自XX.XX.XXX.XXX:56767的连接请求 上午10:39:11。
期望从中接收价值41898字节的数据 XX.XX.XXX.XXX:56767。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到1024个字节的数据。
收到的1024个字节 上午10:39的数据。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到1024个字节的数据。
收到的1024个字节 上午10:39的数据。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到416字节的数据。
收到的1024个字节 上午10:39的数据。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到1024个字节的数据。
收到的1024个字节 上午10:39的数据。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到1024个字节的数据。
收到的1024个字节 上午10:39的数据。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到1024个字节的数据。
收到的1024个字节 上午10:39的数据。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到1024个字节的数据。
收到的1024个字节 上午10:39的数据。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到1024个字节的数据。
收到的1024个字节 上午10:39的数据。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到1024个字节的数据。
收到的1024个字节 上午10:39的数据。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到1024个字节的数据。
收到96个字节的 上午10:39的数据。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到1024个字节的数据。
收到的1024个字节 上午10:39的数据。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到1024个字节的数据。
收到的1024个字节 上午10:39的数据。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到1024个字节的数据。
收到的1024个字节 上午10:39的数据。
在10:39 AM接收到1024个字节的数据。
在10:39 AM接收到1024个字节的数据。
收到的1024个字节 上午10:39的数据。
在10:39 AM接收到512字节的数据。
收到的总字节数,根据提示: 41984。
内存流:包含43434个字节的数据。
如您所见,内存流包含43434字节的数据,即使我希望它仅包含41984字节也是如此。
这会引起很多问题,例如如果我通过写ZipArchive
创建了new ZipArchive(memoryStream);
的新实例,即使我知道我的远程TCP客户端已经发送了一个有效的zip文件,我仍然以InvalidDataException
结尾。
ZipArchive
构造函数中?答案 0 :(得分:3)
问题出在这里,您可以在其中写入数据:
memoryStream.Write(
dataBuffer,
0,
numBytesLeftToReceive < dataBuffer.Length ? numBytesLeftToReceive : dataBuffer.Length);
您完全忽略了收到的数量,而是只检查是否有比自助餐大小更多的数据要接收,以及是否写入了整个缓冲区。
有时您会在输出中看到没有收到完整的缓冲区。但是,您仍然要编写整个缓冲区。
始终根据收到的金额写信。不要根据数据的长度进行任何奇怪的比较:
memoryStream.Write(
dataBuffer,
0,
numBytesReceived);