2015-11-15 62 views
0

我試圖使用C#中的套接字發出HTTP請求/響應。 GET請求出現在下面。空http響應正文

StringBuilder sb = new StringBuilder(); 
sb.AppendFormat("GET http://{0}/ HTTP/1.1\r\n", hostname); 
sb.AppendFormat("Host: {0}\r\n", hostname); 
sb.Append("Connection: keep-alive\r\n"); 
sb.Append(@"Accept:text/html,*/*"); 
sb.Append("\r\n\r\n"); 

其中主機是像 'mit.edu' 或 'facebook.com' 或 'google.com' 或其他任何東西。由於一些奇怪的原因,我只有一個狀態行(帶有200個狀態碼)和標題作爲http響應。但在響應沒有郵件正文:attached srceenshot of my console app

下面是與插座進行所有操作,讓http請求的方法:

public static void DoHttpGetRequest(String hostname, Int16 port = 80) { 
     IPHostEntry ipHostEntry = Dns.GetHostEntry(hostname); 
     IPAddress ipAdress = ipHostEntry.AddressList[0]; 
     IPEndPoint ipEndPoint = new IPEndPoint(ipAdress, port); 

     Socket socket = new Socket(ipAdress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 

     socket.Connect(ipEndPoint); 

     String request = CreateRequest(hostname); 

     Byte[] byteRequest = Encoding.UTF8.GetBytes(request); 
     Byte[] byteResponse = new Byte[1000]; 

     int bytesSent = socket.Send(byteRequest); 
     int bytesReceive = socket.Receive(byteResponse); 

     Console.WriteLine(request); 
     Console.WriteLine(); 
     Console.WriteLine(Encoding.UTF8.GetString(byteResponse, 0, bytesReceive)); 

     socket.Shutdown(SocketShutdown.Both); 
     socket.Close(); 
} 

我首先想到的是,插座沒有收到全來自服務器的響應。在這種情況下,我仍然不知道如何解決問題。

那麼發生了什麼事?錯誤在哪裏?

+0

不知道你在這裏打電話給什麼樣的服務,但如果它給你的http代碼200這意味着好,那麼它一定做了一些事情。可能是服務器端的問題? 你是否擁有這項服務?有沒有機會查看@日誌或從那裏跟蹤代碼? –

+0

@Tendious,thanx爲您的答案。服務不是我的。我爲很多不同的服務運行了很多次代碼。有senate.gov,ex.ua,mit.edu,google.com,fs.to和其他等。所有這些請求得到了他們的代碼200OK或302Found或301和沒有消息正文的迴應。所以我不確定它是關於服務器端的問題。 – Yevtukhoff

回答

1

不要期望在單個接收中獲得完整的響應。你所做的是接收數據,直到你有完整的響應頭(這也可能需要幾個接收調用),然後解析頭以找出響應的時間長度,然後讀取必要的響應數據接聽電話。而且,由於您正在執行HTTP/1.1請求,您還必須處理分塊響應。

我建議更好地使用HTTP庫來處理所有問題。如果你堅持全部通過自己閱讀the specification of HTTP並據此實施。 它也有助於環顧stackoverflow處理類似的請求,因爲對於嘗試首次實現HTTP的用戶而言,這個問題非常典型,對於套接字,TCP和HTTP的工作原理還不夠了解。

+0

RFC 2616已棄用(「*過時:7230,7231,7232,7233,7234,7235 *」)。對於接班人請閱讀這裏:http://www.w3.org/Protocols/和這裏https://tools.ietf。org/html/rfc2616 – alk

+0

@alk:我知道,但指向單個RFC比指向幾個更容易。這些RFC規範中的差異很小,任何瀏覽器的方式都不同於舊規範和新規範。 –

0

我想你應該保持打開更長的時間。插入一個

Thread.Wait(5000); 

可能有所幫助。然後你可以做第二個socket。接受Steffen的建議。也許你可以嘗試以下(等到服務器關閉連接):

while (socket.Connected) do 
{ 
    int bytesReceive = socket.Receive(byteResponse); 
} 

但我沒有測試這個。它更容易使用System.Net.Http.HttpClient

0

我需要做的一切就是接收數據與多個接收呼叫,直到收到所有的響應信息。

do 
{     
    bytesReceive = socket.Receive(byteResponse, byteResponse.Length, 0); 
    response += Encoding.UTF8.GetString(byteResponse, 0, bytesReceive); 
} 
while (bytesReceive > 0); 

感謝大家的幫助!