C#NetworkStream.Read怪胎 [英] C# NetworkStream.Read oddity

查看:189
本文介绍了C#NetworkStream.Read怪胎的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以指出在这个code中的缺陷?我取回一些HTML与TcpClient的。 NetworkStream.Read()似乎从来没有谈论到IIS服务器时结束。如果我使用代理小提琴手相反,它工作正常,而是直接聊到目标服务器的.read()循环时将不会退出,直到连接异常出包含远程服务器已关闭了连接的错误。

Can anyone point out the flaw in this code? I'm retrieving some HTML with TcpClient. NetworkStream.Read() never seems to finish when talking to an IIS server. If I go use the Fiddler proxy instead, it works fine, but when talking directly to the target server the .read() loop won't exit until the connection exceptions out with an error like "the remote server has closed the connection".

internal TcpClient Client { get; set; }

/// bunch of other code here...

try
{

NetworkStream ns = Client.GetStream();
StreamWriter sw = new StreamWriter(ns);

sw.Write(request);
sw.Flush();

byte[] buffer = new byte[1024];

int read=0;

try
{
    while ((read = ns.Read(buffer, 0, buffer.Length)) > 0)
    {
        response.AppendFormat("{0}", Encoding.ASCII.GetString(buffer, 0, read));
    }
}
catch //(SocketException se)
{

}
finally
{
    Close();
}

更新

在调试器的我可以看到整个的反应来通过立即追加到我的StringBuilder(响应)。它只是看起来,当服务器完成发送响应的连接没有被关闭,或者我的code未检测到它。

In the debugger, I can see the entire response coming through immediately and being appended to my StringBuilder (response). It just appears that the connection isn't being closed when the server is done sending the response, or my code isn't detecting it.

结论
正如已经在这里说,这是最好采取协议的产品(在HTTP的Content-Length头的情况下),以确定何时交易完成的优势。然而,我发现,并不是所有的页面有内容长度集。所以,我现在用的是混合解决方案:

Conclusion As has been said here, it's best to take advantage of the offerings of the protocol (in the case of HTTP, the Content-Length header) to determine when a transaction is complete. However, I've found that not all pages have content-length set. So, I'm now using a hybrid solution:


  1. 有关的所有交易,设置请求的连接头为关闭,从而使服务器从保持套接字打开气馁。这改善了机会,该服务器将关闭连接时,它是通过响应您的要求。

  1. For ALL transactions, set the request's Connection header to "close", so that the server is discouraged from keeping the socket open. This improves the chances that the server will close the connection when it is through responding to your request.

如果的Content-Length 设置,用它来确定当一个请求已完成。

If Content-Length is set, use it to determine when a request is complete.

否则,该的NetworkStream的应为requestTimeout属性设置为一个大的,但合理的,价值像1秒。然后,在循环 NetworkStream.Read()直到一)发生超时,或b)比你要求你读的字节数更少。

Else, set the NetworkStream's RequestTimeout property to a large, but reasonable, value like 1 second. Then, loop on NetworkStream.Read() until either a) the timeout occurs, or b) you read fewer bytes than you asked for.

感谢大家的出色和详尽的答复。

Thanks to everyone for their excellent and detailed responses.

推荐答案

不知道这是有帮助或没有,但与HTTP 1.1的服务器底层的连接可能不被关闭,所以也许该流不得到要么关闭?这个想法是,你可以重复使用该连接发送一个新的请求。我认为你必须使用的内容长度。另外也可以使用Web客户端或WebRequest的类来代替。

Not sure if this is helpful or not but with HTTP 1.1 the underlying connection to the server might not be closed so maybe the stream doesn't get closed either? The idea being that you can reuse the connection to send a new request. I think you have to use the content-length. Alternatively use the WebClient or WebRequest classes instead.

这篇关于C#NetworkStream.Read怪胎的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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