2010-12-06 58 views
0

我想寫一個簡單的控制檯應用程序,POST到一個頁面並輸出返回的HTML到控制檯。C#套接字編程 - 如何確定接收緩衝區的大小

我的代碼有效,但它只返回響應的一部分。我可以想出使其工作的唯一方法是將字節緩衝區設置爲我知道足夠大以便返回內容的大小。

有沒有辦法檢查緩衝區需要多大來獲得完整的響應?

這裏是代碼...

Uri uri = new Uri(@"http://bobssite/"); 

// Get the IPAddress of the website we are going to and create the EndPoint 
IPAddress ipAddress = Dns.GetHostEntry(uri.Host).AddressList[0]; 
IPEndPoint endPoint = new IPEndPoint(ipAddress, 80); 

// Create a new Socket instance and open the socket for communication 
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); 
socket.Connect(endPoint); 

// Attempt to send the request 
int byteCount = 0; 
try 
{ 
    string requestString = 
     "POST " + uri.PathAndQuery + " HTTP/1.1\r\n" + 
     "Host: " + uri.Host + "\r\n" + 
     "Content-Type: application/x-www-form-urlencoded\r\n" + 
     "Content-Length: 11\r\n" + 
     "\r\n" + 
     "user=bob"; 

    byte[] bytesToSend = Encoding.ASCII.GetBytes(requestString); 
    byteCount = socket.Send(bytesToSend, SocketFlags.None); 
} 
catch (SocketException se) 
{ 
    Console.WriteLine(se.Message); 
} 

// Attempt to receive the response 
if (byteCount > 0) 
{ 
    byte[] bytesReceived = new byte[256]; 
    try 
    { 
     byteCount = socket.Receive(bytesReceived, SocketFlags.None); 
    } 
    catch (Exception e) 
    { 
     System.Diagnostics.Debug.WriteLine("HELP!! --> " + e.Message); 
    } 

    // Out the html we received 
    string html = Encoding.ASCII.GetString(bytesReceived); 
    Console.WriteLine(html); 
} 
else 
{ 
    Console.WriteLine("byteCount is zero!"); 
} 

Console.Read(); 

回答

0

我把一個循環內的Receive調用保持調用接收,直到接收到的字節爲零,並將返回的數據附加到一個字符串變量中。

工作守則....

Uri uri = new Uri(@"http://bobssite/"); 

// Get the IPAddress of the website we are going to and create the EndPoint 
IPAddress ipAddress = Dns.GetHostEntry(uri.Host).AddressList[0]; 
IPEndPoint endPoint = new IPEndPoint(ipAddress, 80); 

// Create a new Socket instance and open the socket for communication 
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); 
socket.Connect(endPoint); 

// Attempt to send the request 
int byteCount = 0; 
try 
{ 
    string requestString = 
     "POST " + uri.PathAndQuery + " HTTP/1.1\r\n" + 
     "Host: " + uri.Host + "\r\n" + 
     "Content-Type: application/x-www-form-urlencoded\r\n" + 
     "Content-Length: 11\r\n" + 
     "\r\n" + 
     "user=bob"; 

    byte[] bytesToSend = Encoding.ASCII.GetBytes(requestString); 
    byteCount = socket.Send(bytesToSend, SocketFlags.None); 
} 
catch (SocketException se) 
{ 
    Console.WriteLine(se.Message); 
} 

// Attempt to receive the response 
if (byteCount > 0) 
{ 
    byte[] bytesReceived = new byte[256]; 
    string page = ""; 
    try 
    { 
     while (byteCount > 0) 
     { 
      byteCount = socket.Receive(bytesReceived, SocketFlags.None); 
      page += Encoding.ASCII.GetString(bytesReceived); 
      Array.Clear(bytesReceived, 0, bytesReceived.Length); 
     } 
    } 
    catch (Exception e) 
    { 
     System.Diagnostics.Debug.WriteLine("HELP!! --> " + e.Message); 
    } 

    // Out the html we received 
    Console.WriteLine(page); 
} 
else 
{ 
    Console.WriteLine("byteCount is zero!"); 
} 

Console.Read(); 
1

一般來說,你會從插座中循環讀取,直到沒有數據左。如果你想避免這種情況,你可以首先閱讀一個猜測大到足以包含HTTP響應頭的塊,解析出Content-Length行,並使用結果分配你的下一個緩衝區 - 但這看起來像一個痛苦。

是否有一個原因,你在這麼低的水平,而不是使用WebClient class

+0

我知道我可以用Web客戶端或HttpWebRequest的做到這一點很容易,但我強迫自己使用Socket類。 – thiag0 2010-12-06 19:59:44

2

這是矯枉過正只是做一個POST!您的所有代碼都可以工作,但使用WebClient會使呼叫減少到幾行。

帶有TCP套接字的一點是,您不斷閱讀,直到您收到標識符以關閉會話。現在您正在使用HTTP,這是通過讀取標題並找到content-length的值並從流中讀取確切的字節長度,並且沒有關閉會話的標識符。

+0

我強迫自己使用套接字類。 – thiag0 2010-12-06 20:02:18

+0

夠公平的,但它是很多的工作和非常低的水平。您還將看到一些可能會發生的問題,並且已經被更高級的課程所關注。 – Aliostad 2010-12-06 20:04:06