我正在实现一个简单的HTTP客户端,只是连接到一个Web服务器,并获得其默认主页。这是和它的作品不错:真的很奇怪的HTTP客户端在C#中使用TcpClient
using System;
using System.Net.Sockets;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TcpClient tc = new TcpClient();
tc.Connect("www.google.com", 80);
using (NetworkStream ns = tc.GetStream())
{
System.IO.StreamWriter sw = new System.IO.StreamWriter(ns);
System.IO.StreamReader sr = new System.IO.StreamReader(ns);
string req = "";
req += "GET/HTTP/1.0\r\n";
req += "Host: www.google.com\r\n";
req += "\r\n";
sw.Write(req);
sw.Flush();
Console.WriteLine("[reading...]");
Console.WriteLine(sr.ReadToEnd());
}
tc.Close();
Console.WriteLine("[done!]");
Console.ReadKey();
}
}
}
当我从上面的代码删除下面的线,在sr.ReadToEnd程序块。
req += "Host: www.google.com\r\n";
我甚至取代sr.ReadToEnd与sr.Read,但它无法读取任何东西。我使用Wireshark的,看看有什么发生:
正如你看到的,我的GET请求后,谷歌不响应该请求被一次又一次地重发。看来我们必须在HTTP请求中指定主机部分。奇怪的部分是我们不。我用telnet发送这个请求,并得到了谷歌的回应。我还捕获了telnet发送的请求,并且与我的请求完全相同。
我尝试了很多其他网站(例如雅虎,微软),但结果是一样的。
因此,telnet延迟是否会导致web服务器的行为不同(因为在telnet中我们实际上是类型是字符,而不是将它们一起发送到1个数据包中)。
另一个奇怪的问题是当我改变HTTP/1.0上HTTP/1.1,程序总是块sr.ReadToEnd线。我想这是因为Web服务器不关闭连接。
的一个解决方案是使用读(或的ReadLine)和ns.DataAvailable读取响应。但我无法确定我是否已阅读所有回复。我如何读取响应并确保HTTP/1.1请求的响应中没有剩余字节?
注: 作为W3说,
the Host request-header field MUST accompany all HTTP/1.1 requests
(我这样做是为了我的HTTP/1.1请求)。但我还没有看到这样的事情HTTP/1.0。另外发送请求没有主机头使用telnet工作没有任何问题。
更新:
推标志的TCP段被设置为1。我也试过netsh winsock重置重置我的TCP/IP协议栈。测试计算机上没有防火墙和防病毒软件。数据包实际上被发送,因为安装在另一台计算机上的Wireshark可以捕获它。
我也尝试了一些其他的请求。例如,
string req = "";
req += "GET/HTTP/1.0\r\n";
req += "s df slkjfd sdf/ s/fd \\sdf/\\\\dsfdsf \r\n";
req += "qwretyuiopasdfghjkl\r\n";
req += "Host: www.google.com\r\n";
req += "\r\n";
在所有的请求的类型,如果我省略主持人:一部分,Web服务器不响应,如果有主持人:一部分,甚至是无效的请求(只就像上面的请求一样)将被响应(通过400:HTTP Bad Request)。
nos说主持人:部分是不需要在他的机器上,这使情况更奇怪。
我不知道这是不是问题,但不应该使用HTTP响应中的内容长度来确定您应该读取多少字节,然后从响应的主体读取那些字节? – Aziz 2009-09-09 17:00:29
@Aziz。也许这是一个很好的解决方案,而不是使用** ReadToEnd **。但在问题的第一部分中,我没有收到来自服务器的任何内容(即使是一个字节)。 – Isaac 2009-09-09 17:09:16
这段代码在有或没有Host:头的情况下工作。 GET请求的TCP段是否设置了PUSH位? - 不是你可以做很多事情,但如果没有设置它可以解释重发 – nos 2009-09-09 18:48:30