2009-05-03 15 views
0

ソケットを使用して簡単なSNPP(Simple Network Paging Protocol)クライアントを作成しようとしています。サーバー間のわずかな不一致を除いて、すべてがうまくいくように見えます。ソケットから単一のバッファにチャンクされたデータを受信

私はコマンドを送信するときに、通常は1つのデータチャンクである返信を読む必要があります。ただし、SprintのSNPPサーバーは2つの部分で応答を送信します。データの最初のチャンクはステータスコードの最初の桁です。 2番目のチャンクは残りのチャンクです。現時点では

20 Gateway ready 

:私は残りの部分を取得するために別の空のコマンドを送信する必要が

2 

:私は「220 Gatewayの準備」応答を受信しようとすると、例えば、それは次のように到着します、私が使用しています:

byte[] buffer = new byte[256]; 
socket.Receive(buffer); 

をどのように私は、データの各チャンクのための別のバッファを割り当てずにコマンドを発行した後、利用可能なデータのすべてを受け取っていることを確認することができますか?

答えて

3

using (var resultStream = new MemoryStream()) 
{ 
    const int CHUNK_SIZE = 2 * 1024; // 2KB, could be anything that fits your needs 
    byte[] buffer = new byte[CHUNK_SIZE]; 
    int bytesReceived; 
    while ((bytesReceived = socket.Receive(buffer, buffer.Length, SocketFlags.None)) > 0) 
    { 
     byte[] actual = new byte[bytesReceived]; 
     Buffer.BlockCopy(buffer, 0, actual, 0, bytesReceived); 
     resultStream.Write(actual, 0, actual.Length); 
    } 

    // Do something with the resultStream, like resultStream.ToArray() ... 
} 
+0

すべてのサイズのチャンクを処理するので、ただし、最初の応答を受け取った後、アプリケーションは新しいデータがあるまで応答を停止します。デバッガはwhile条件でハングすることを示します。 –

1

Socket.Availableプロパティをチェックして、Receiveをもう一度呼び出す必要があるかどうかを確認してください。

0

私はあなたの質問を理解すると思います。 Socket.Receiveのこのオーバーロードによって、オフセット位置を指定してデータを配置する整数を渡すことができます。あなたの例のように最初の呼び出しで1バイトが得られたら、オフセット1でこのオーバーロードを呼び出して、同じバッファを使用することができます。

0

Socket.Receiveは、受信したバイト数である整数を返します。これが1かどうかを確認して、Receiveにもう一度お電話ください。私はあなたがこのようなデータの読み取りをお勧めチャンクの応答を

byte[] buffer = new byte[256]; 
int len = socket.Receive(buffer); 

if (len == 1) 
    socket.Receive(buffer, 1, buffer.Length - 1, SocketFlags.None); 
-1

すべて、

ウェブサーバは「チャンク」にデータを送信しているとき、それはそれで各チャンクの前ですlength(16進値を示す文字列)。

チャンクサイズ[;チャンクの拡張] チャンクデータ

例えば:チャンクへの15バイト:

F。 123456789ABCDEF

ソケットからHTTPデータを受信する際の最大の問題は、読み取るデータ量を決定することです。使用可能なデータをすべて受信してRecieveメソッドを再度呼び出すと、Recieveメソッドはリモートソケットが送信するまでブロックされますより多くのデータ、HTTP/1.0接続では決して起こらないでしょう。

ソケットをラップするリーダーを実装する必要があります。それはバッファにデータを受け取り、13の後に10(CRLF)が続くまでバッファの内容を読み込む "ReadLine"メソッドを提供する必要があります。

関連する問題