我正在實現一個簡單的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