2011-07-13 12 views
9

@ Len-Holgate in this questionのアドバイスに基づいて、私は非同期的に0バイトの読み取りを要求しています。コールバックでは、データが利用可能でブロックされないことがわかっているので、同期読み取りで利用可能なバイトを受け取ります。これはとても効率的で素晴らしいようです。SslStream相当のTcpClient.Available?

しかし、私はSslStreamのオプションを追加して、アプローチが分かりません。 0バイトの読み込みは問題ありませんが、SslStreamはバイトを復号化し、TcpClientのバッファにゼロバイトカウントを残します(適切に)。読み込み可能なSslStreamのバイト数を判断できません。

この周りに簡単なトリックがありますか?


ちょうどコンテキストのいくつかのコード、:

sslStream.BeginRead(this.zeroByteBuffer, 0, 0, DataAvailable, this); 

と(正確に0を返す)EndRead()の後に、DataAvailableが含まれています

// by now this is 0, because sslStream has already consumed the bytes 
available = myTcpClient.Available; 

if (0 < available) // Never occurs 
{ 
    // this part can be distractingly complicated, but 
    // it's based on the available byte count 
    sslStream.Read(...); 
} 

そしてによるプロトコルへのバイトごとに評価し、可変バイト幅のユニコードとデコードを行う必要があります。私はバイトごとに非同期に読み込む必要はありません!

+3

私はSSLの有無にかかわらず、同期または非同期の多くのソケットベースのアプリケーションを構築しました。しかし、私は利用可能なバイト数を知る必要がある状況に遭遇したことはありません。私はこれまでに行って、それに頼っているアプリケーションを呼ぶだろう。あなたのコードがなぜこれを必要としているのか説明できますか? byteBuffer.Lengthに何バイトも要求しないのはなぜですか? – dtb

+1

この場合、改行文字の前に受信する必要があるバイト数はわからないからです。 1024バイトを要求すると、1024バイトが使用可能になるまで(またはソケットが閉じられているためストリームの終わりに到達するまで)コールバックは返されません。私はこれについて間違っていない限り? –

+2

ReadとBeginReadの両方が利用可能なものだけを返します。利用可能なものがない場合は、少なくとも1バイトが使用可能になるか、ストリームが閉じられるまで待機します。たとえば、1024バイトを要求すると、1〜1024バイトが返されますが、正確に1024バイトが受信されるまで待機しません。 – dtb

答えて

1

私が正しく理解していれば、あなたのメッセージは特定の文字で区切られており、メッセージが複数の断片に分割されている場合にはすでにStringBuilderを使用しています。

デリミタを無視してデータを読み込んだり、利用可能になった時点でデータを追加したり、区切り文字としてローカルのStringBuilderを調べることができます。見つかった場合、デリミタがなくなるまで、sb.ToString(0, delimiterIndex)sb.Remove(0, delimiterIndex)を使用して1つのメッセージを抽出できます。

これは、2つのメッセージを同時に受信する場合にも適用されます。