2012-07-31 81 views
1

我创建简单的代理服务器,但我遇到一个奇怪的现象,我下面的代码:的NetworkStream不支持查找操作

var clientRequestStream = _tcpClient.GetStream(); 
var requestHeader = clientRequestStream.GetUtf8String(); 

GetUtf8StringStream类读取流的扩展方法(包含HttpRequest标题)。我需要提取这些标题才能访问主机和请求的网址。一旦阅读NetworkStream完成。我需要执行查找操作并设置它的clientRequestStream.Position = 0;,因为我必须读取该流并将其写入另一个远程NetworkStream

我不知道该如何解决这个问题。任何建议都会有帮助。


编辑:我也试图复制的NetworkStream到的MemoryStream然后执行寻求MemoryStream的操作,没有例外,但是当我想从的NetworkStream读取其缓冲总是总是空的。

另外我用反射器看看Stream.CopyTo里面发生了什么。见下面的代码:

private void InternalCopyTo(Stream destination, int bufferSize) 
    { 
     int num; 
     byte[] buffer = new byte[bufferSize]; 
     while ((num = this.Read(buffer, 0, buffer.Length)) != 0) 
     { 
      destination.Write(buffer, 0, num); 
     } 
    } 

这是CopyTo做的。即使我用CopyTo问题仍然没有解决。因为它读源(Here NetworkStream)到最后。我有另一种方式来处理这种情况?

回答

4

您是否正在阅读此流直到结束?如果是这样,我建议你只是将整个内容复制到一个MemoryStream,然后你可以在上找到来表达你的内容。在.NET 4中它是特别容易与Stream.CopyTo

MemoryStream dataCopy = new MemoryStream(); 
using (var clientRequestStream = _tcpClient.GetStream()) 
{ 
    clientRequestStream.CopyTo(dataCopy); 
} 
dataCopy.Position = 0; 
var requestHeader = dataCopy.GetUtf8String(); 

是有意义的NetworkStream不被可搜索的 - 它只是一个数据流,一个服务器是给你的。除非你可以告诉服务器倒带(这在某些情况下甚至是有意义的),否则没有办法寻找,除非缓存尽可能多的数据,因为你需要倒带 - 这基本上是拷贝到MemoryStream所做的,蛮力时尚。

+0

乔恩我没有复制NetworkStream到MemoryStream,但是当我想读取缓冲区总是空的。 – saber 2012-07-31 21:17:28

+0

Jon我也测试过CopyTo,但是需要一天的时间将缓冲区复制到MemoryStream。我不知道为什么。 – saber 2012-07-31 21:24:57

+0

@SaberAmani:那么网络流中有什么?如果服务器保持连接打开,它将不会完成复制。至于你的第一条评论 - 这将表明你没有正确地复制数据。很难说如何没有看到你的代码。 – 2012-07-31 22:41:14

2

正如你所发现的,NetworkStream是不可搜索的。
NetworkStream直接从网络为您提供数据。

您应该将数据读入MemoryStream并重新使用。

+0

我编辑帖子,看看 – saber 2012-07-31 21:15:15

+0

您无法将MemoryStream分配给NetworkStream。您需要直接使用MemoryStream。 – SLaks 2012-07-31 21:20:11

+0

我也测试了CopyTo,但是我需要一天的时间将缓冲区复制到MemoryStream。我不知道为什么。 – saber 2012-07-31 21:24:43

1

假设你不想正确重写GetUtf8String方法不需要寻求...

最简单的办法是复制流MemoryStream的第一和比你流,你可以寻找你一样想。 (.Net4 +)

请注意,您需要通过将Position属性设置为0(copiedStream.Position=0)或通过基于缓冲区和长度创建新的(最好是只读的)克隆流来查找结果MemoryStream。的第一个内存流。

+0

我编辑帖子,看看 – saber 2012-07-31 21:15:04

+0

@SaberAmani,更新。请注意Jon Skeet的答案(+1)包含您需要的确切代码。 – 2012-07-31 21:19:46

+0

我也测试了CopyTo,但它需要一天将缓冲区复制到MemoryStream,应用程序停止在我想要复制的位置。我不知道为什么。 – saber 2012-07-31 21:25:54