TcpClient.GetStream().CopyTo(MemoryStream) 停止应用程序继续? [英] TcpClient.GetStream().CopyTo(MemoryStream) stops application from continuing?

查看:33
本文介绍了TcpClient.GetStream().CopyTo(MemoryStream) 停止应用程序继续?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试执行一些非常基本的网络操作,但遇到了一些问题.

I'm trying to perform some extremely basic network operations, yet I'm having some trouble.

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

Originally, I was trying to use NetworkStream.Length to create a new byte[], but it became apparent that this is not possible since NetworkStream does not support seek operations.

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

I then found some examples showing how to copy the NetworkStream to a MemoryStream, which allows seek operations. So far, so good.

或者是吗?

一旦 using 语句的作用域被命中,应用程序就基本上停止了.它仍在运行,做某事,但我真的不知道是什么.代码如下:

Once the scope of the using statement gets hit, the application essentially stops. It's still running, doing something, but I can't really tell what. Here's the code:

    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 以进行一些处理,但事实证明,仅此一项任务就比应有的困难.

So there's where my problem has me completely stumped. I need to copy my NetworkStream to a MemoryStream to do some processing, but this task alone is proving more difficult than it should be.

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

Has anybody encountered this issue before?

推荐答案

TCP 流通常不会终止 - 即入站流在技术上一直处于活动状态,直到套接字被破坏(或至少:套接字的另一端选择关闭它们的出站链接,也许保持它们的入站链接打开以获得回复).

A TCP stream is often not terminated - i.e. the inbound stream is technically alive until the socket is broken (or at a minimum : the other end of the socket elects to close their outbound link, perhaps keeping their inbound link open to get the reply).

现在:CopyTo 将要读取到流的结尾.没有尽头的流.Read 的行为是:

Now: CopyTo will want to read to the end of the stream. Of a stream that has no end. The behaviour of Read is:

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

如果超时未启用,并且套接字永远不会关闭,则:boom.

If timeouts aren't enabled, and the socket doesn't close ever, then: boom.

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

For this reason, socket code usually needs to be very careful in terms of "framing" - i.e. knowing how much data to read as a unit. This is often done via some form length-prefix in the data stream, i.e. "the next message is 27 bytes" - then you know to only try to read 27 more bytes, because reading a 28th might block you forever. In text-based protocols, this is often done using sentinel values like line-feed.

这篇关于TcpClient.GetStream().CopyTo(MemoryStream) 停止应用程序继续?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆