我正在创建简单的代理服务器,但我遇到了一个奇怪的情况,我遵循了以下代码:
var clientRequestStream = _tcpClient.GetStream();
var requestHeader = clientRequestStream.GetUtf8String();
GetUtf8String
是Stream
类的扩展方法,它读取流(包含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)到最后。我有另一种方法来处理这种情况吗?
答案 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()之类的东西会导致应用程序阻塞。