首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过TCP: MemoryStream接收数据比预期包含更多的数据

通过TCP: MemoryStream接收数据比预期包含更多的数据
EN

Stack Overflow用户
提问于 2019-04-30 10:58:02
回答 1查看 73关注 0票数 0

我托管一个服务器,它接收来自远程TCP客户端的数据(我也控制它)。下面是处理传入数据的方法:

代码语言:javascript
复制
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是从标头检索的信息。

下面是我的控制台上的输出:

接受XX.XX.XXX.XXX:56767在2019年4月30日10:39:11的连接请求 期望从XX.XX.XXX.XXX:56767接收41898字节的数据。 在上午10:39接收1024字节的数据AM.Received 1024字节 在上午10:39收到1024字节的数据 在上午10:39接收1024字节的数据AM.Received 1024字节 在上午10:39收到1024字节的数据 在上午10:39接收1024字节的数据AM.Received 416字节 在上午10:39收到1024字节的数据 在上午10:39接收1024字节的数据AM.Received 1024字节 在上午10:39收到1024字节的数据 在上午10:39接收1024字节的数据AM.Received 1024字节 在上午10:39收到1024字节的数据 在上午10:39接收1024字节的数据AM.Received 1024字节 在上午10:39收到1024字节的数据 在上午10:39接收1024字节的数据AM.Received 1024字节 在上午10:39收到1024字节的数据 在上午10:39接收1024字节的数据AM.Received 1024字节 在上午10:39收到1024字节的数据 在上午10:39接收1024字节的数据AM.Received 1024字节 在上午10:39收到1024字节的数据 在上午10:39接收1024字节的数据AM.Received 1024字节 在上午10:39收到96字节的数据 在上午10:39接收1024字节的数据AM.Received 1024字节 在上午10:39收到1024字节的数据 在上午10:39接收1024字节的数据AM.Received 1024字节 在上午10:39收到1024字节的数据 在上午10:39接收1024字节的数据AM.Received 1024字节 在上午10:39收到1024字节的数据 在上午10:39接收1024字节的数据AM.Received 1024字节 在上午10:39收到1024字节的数据 接收到512个字节的数据在10:39 AM.Total接收到的字节数,据统计: 41984。 内存流:包含43434字节的数据。

正如您所看到的,内存流包含43434字节的数据,尽管我希望它只包含41984字节。

这导致了许多问题,例如,如果我通过编写ZipArchive创建一个新的new ZipArchive(memoryStream);实例,那么我将得到一个InvalidDataException,尽管我知道远程TCP客户端已经发送了一个有效的zip文件。

  1. 为什么内存流包含的字节比实际通过TCP接收的要多?
  2. 我如何删除这些“垃圾数据”(因为缺少更好的术语),以便我能够成功地重构发送给我的数据,例如将内存流传递到ZipArchive构造函数中?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-30 11:08:44

问题是在这里您需要编写数据:

代码语言:javascript
复制
memoryStream.Write(
            dataBuffer,
            0,
            numBytesLeftToReceive < dataBuffer.Length ? numBytesLeftToReceive : dataBuffer.Length);

您完全忽略了收到的数量,相反,您只需检查要接收的数据是否比自助餐大小还要多,以及是否需要编写整个缓冲区。

您可以在输出中看到,有时没有接收到完整的缓冲区。然而,您仍然可以编写整个缓冲区。

一定要根据收到的金额来写。不要根据数据的长度做任何奇怪的比较:

代码语言:javascript
复制
memoryStream.Write(
            dataBuffer,
            0,
            numBytesReceived);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55919470

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档