2010-12-06 7 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呼び出しをループ内に置いて、受信バイトがゼロになるまで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

2

これは、過剰殺傷です。すべてのコードが動作する可能性がありますが、WebClientを使用すると、2〜3行に短縮されます。

TCPソケットのある点は、セッションを閉じるための識別子を受け取るまで読み続けることです。 HTTPを使用しているので、ヘッダーを読み取り、値content-lengthを見つけ、ストリームから正確なバイト長を読み取り、セッションを閉じるための識別子はありません。

+0

私は自分自身でSocketsクラスを使用しています。 – thiag0

+0

十分に公正ですが、それは多くの仕事と非常に低いレベルです。あなたはまた、ソケットで起こり、すでに上級クラスで扱われている問題のホストにさらされます。 – Aliostad

+0

私は同意しますが、私はこの問題では選択肢がありませんでした:)これは唯一の再生コードです。深刻なものではありません。あなたのご意見ありがとうございます! – thiag0

0

レスポンスヘッダーのContent-Length値を確認したい場合があります。

また、サーバーはchunked transfer encodingを使用してデータを送信している可能性があります。実際の長さ(たとえば、オンザフライで圧縮されているデータなど)を知る前に送信を開始できます。

RFC for HTTP protocolも参照してください。

+0

これは実現可能な方法だと思われますが、コンテンツの長さを確認する必要はありません。助けてくれてありがとう! – thiag0

関連する問題