NetworkStream不支持搜索操作

时间:2012-07-31 21:08:18

标签: c# .net sockets network-programming tcpclient

我正在创建简单的代理服务器,但我遇到了一个奇怪的情况,我遵循了以下代码:

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

GetUtf8StringStream类的扩展方法,它读取流(包含HttpRequest标头)。我需要提取这些标头以访问Host和Requested Url。一旦读完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 个答案:

答案 0 :(得分: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不可寻找是有意义的 - 它只是服务器给你的数据流。除非你能告诉服务器倒带(在某些情况下甚至才有意义),除非有什么东西可以缓存你需要倒带的数据,否则无法寻找 - 这基本上就是复制到{ {1}}以一种非常蛮力的方式做到了。

答案 1 :(得分:2)

正如您所发现的,NetworkStream是不可寻找的 NetworkStream直接从网络提供数据。

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

答案 2 :(得分:1)

假设您不想正确地重写GetUtf8String方法而不需要搜索......

最简单的方法是首先将流复制到MemoryStream,而不是拥有流,您可以根据需要进行搜索。 Stream.CopyTo将负责复制(.Net4 +)

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

答案 3 :(得分:0)

您将无法设置clientRequestStream.Position = 0,因为NetworkStream是仅向前的。见这里:http://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.position.aspx

注意以与常规流相同的方式思考NetworkStream。例如,在StreamReader上使用Peek()之类的东西会导致应用程序阻塞。