谁能指出这段代码的缺陷?我正在使用 TcpClient 检索一些 HTML。与 IIS 服务器通信时,NetworkStream.Read() 似乎永远不会完成。如果我改用 Fiddler 代理,它可以正常工作,但是当直接与目标服务器对话时,.read() 循环不会退出,直到连接异常出现“远程服务器已关闭连接”之类的错误。
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(响应)中。当服务器完成发送响应或我的代码没有检测到它时,似乎连接没有关闭。
结论 正如这里所说的,最好利用协议的提供(在 HTTP 的情况下,Content-Length 标头)来确定事务何时完成。但是,我发现并非所有页面都设置了内容长度。所以,我现在使用混合解决方案:
对于所有事务,将请求的
Connection
标头设置为“关闭”,以阻止服务器保持套接字打开。这提高了服务器在响应您的请求时关闭连接的机会。如果
Content-Length
已设置,则使用它来确定请求何时完成。否则,将 NetworkStream 的 RequestTimeout 属性设置为一个较大但合理的值,例如 1 秒。然后,循环
NetworkStream.Read()
直到 a) 发生超时,或者 b) 您读取的字节数少于您要求的字节数。
感谢大家出色而详细的回复。