我正在尝试执行一些非常基本的网络操作,但我遇到了一些麻烦。
最初,我试图使用 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
进行一些处理,但事实证明,仅此一项任务就比应有的困难得多。
以前有人遇到过这个问题吗?
通常不会终止 - 即入站流在技术上是活动的,直到套接字被破坏(或者至少:套接字的另一端选择关闭其出站链接,也许保持其入站链接打开以获取回复(。
现在:CopyTo
希望读到流的末尾。没有尽头的溪流。Read
的行为是:
- 阻止,直到至少有一个字节可用...
- 或者直到流关闭...
- 或直到超时
如果未启用超时,并且套接字从未关闭,则:繁荣。
出于这个原因,套接字代码通常需要在"成帧"方面非常小心 - 即知道作为一个单元要读取多少数据。这通常是通过数据流中的一些表单长度前缀来完成的,即"下一条消息是 27 个字节"——然后你知道只尝试再读取 27 个字节,因为读取第 28 个字节可能会永远阻止你。在基于文本的协议中,这通常使用前哨值(如换行(来完成。