2009-06-09 8 views
1

私は、非同期ソケットを使って可変長メッセージを転送する方法について、an article on Vadym Stetsiak's blogを読んでいました。私が求めたすべてのバイトを読み取らずに非同期受信を返すことはできますか?

彼は言う:サーバーに到着したとき、複数のメッセージ

は何を期待しますか? 複数のメッセージを扱う際には、受信操作によってネットから読み取られる任意のバイト数が返されることを覚えておかなければなりません。通常、このサイズはReceiveメソッドまたはBeginReceiveメソッドでは0〜指定されたバッファ長です。

したがって、私がBeginReceiveに100バイトを読み込ませるように指示しても、それはそれよりも読みにくくなり、???を返します。 私はネットワーク対応ソフトウェア(TCP/IP)を開発しています。私は常に要求したのと同じ正確なバイト数を受け取ります。

私は論理を理解していません。なぜなら、私が求めたすべてのバイトを受け取らなかった場合、Receiveは非同期的に完了するのです。

多分IP対TCPと関係がありますか?

答えて

2

ソケットが非同期モードで動作している場合、ソケットは非同期モードで動作していて、その時点で実際に要求されたバイト数を最大で要求された量まで返しますが、要求された量よりも少なく(通常は)与えられた読書。毎回要求するバイト数を保証するものではありません。あなたは最終的に必要なバイトをすべて取得するまで何度も何度も何度も何度も何度も読み続ける必要があります。残っているものをキャッシュするので、後でより多くのバイトが利用できるように処理できます。これはまさにVadymのサンプルコードがやっていることです。このタイプの読み込みは、他の処理を続行している間にバックグラウンドでソケット受信バイトを持っているという点で非同期であり、さらに多くのバイトが利用可能になったときに通知します。

あなたが考えているのは、ソケットが同期モードで動作することです。コードが作業を続ける前に、要求されたバイトがすべて到着するのを待ちます。

0

イーサネットフレームが到着すると、イーサネットデバイスドライバはフレーム全体をそのメモリにコピーします。フレーム全体をコピーした後でのみ、上位レイヤ(TCP)に通知します。 TCPレイヤーはそのデータをバッファーにコピーし、ソケットレイヤーを呼び出します。次に、ソケット層は、利用可能なデータをソケットバッファと呼ばれるバッファ空間にコピーする。最後に、データはユーザバッファにコピーされ、プロセスに通知されます。 1)イーサネットフレームが要求されたサイズより小さい場合 2)TCPバッファサイズ( sysctlパラメータ(linuxのnet.ipv4.tcp_rmem)が要求されたサイズより小さいかどうかを確認することができます。 3)ソケットバッファサイズ(SO_RCVBUFを使用してsetsockopt()によってアプリケーション固有のサイズを設定できる)が要求されたサイズより小さい場合。

指定されたユーザーバッファーサイズが完全なフレームを収容するのに十分な大きさである場合、フレーム全体が常にユーザーバッファーにコピーされます。

IP層にはここで果たす役割はありません。

0

はい、これは実際には奇妙な動作です。しかし、ここに私はそれを見ている..それは間違っているかもしれませんが、それは私がセッションをデバッグしている時間が長引いた後、自分自身に説明する方法です: -/

通常受信(同期)を使用すると、 BeginReceive(非同期)を使用すると、で開始してnバイトを読み取るときに呼び出されます。

つまり、実際にはnバイトを読み込もうとします。終了時ではなく、受信を開始するタイミングを伝えます。そして、時々、nバイトの読み込みは不可能ですが、残念ながらあなたのbeginシグナルは既に呼び出されています。

名前が混乱していると私は同意します。

幸運!

関連する問題