TcpClient.GetStream().CopyTo(MemoryStream)阻止应用程序继续

本文关键字:应用程序 继续 CopyTo GetStream TcpClient MemoryStream | 更新日期: 2023-09-27 18:34:55

我正在尝试执行一些非常基本的网络操作,但我遇到了一些麻烦。

最初,我试图使用 NetworkStream.Length 创建一个新的byte[],但很明显这是不可能的,因为NetworkStream不支持搜索操作。

然后我找到了一些示例,展示了如何将NetworkStream复制到允许搜索操作的MemoryStream。目前为止,一切都好。

还是吗?

一旦 using 语句的范围被击中,应用程序基本上就会停止。它仍在运行,做一些事情,但我真的说不出是什么。代码如下:

    void HandleClientComm(object client)
    {
        TcpClient tcpClient = (TcpClient)client;
        //copy client stream to memory stream to allow seek operations
        MemoryStream clientStream = new MemoryStream();
        using (var clientRequestStream = tcpClient.GetStream())
        {
            clientRequestStream.CopyTo(clientStream);
        }
        //...
    }

所以我的问题让我完全难倒了。我需要将NetworkStream复制到MemoryStream进行一些处理,但事实证明,仅此一项任务就比应有的困难得多。

以前有人遇到过这个问题吗?

TcpClient.GetStream().CopyTo(MemoryStream)阻止应用程序继续

TCP 流

通常不会终止 - 即入站流在技术上是活动的,直到套接字被破坏(或者至少:套接字的另一端选择关闭其出站链接,也许保持其入站链接打开以获取回复(。

现在:CopyTo希望读到流的末尾。没有尽头的溪流。Read的行为是:

  • 阻止,直到至少有一个字节可用...
  • 或者直到流关闭...
  • 或直到超时

如果未启用超时,并且套接字从未关闭,则:繁荣。

出于这个原因,套接字代码通常需要在"成帧"方面非常小心 - 即知道作为一个单元要读取多少数据。这通常是通过数据流中的一些表单长度前缀来完成的,即"下一条消息是 27 个字节"——然后你知道只尝试再读取 27 个字节,因为读取第 28 个字节可能会永远阻止你。在基于文本的协议中,这通常使用前哨值(如换行(来完成。