- ベストアンサー
メッセージの受信終了方法についてのアドバイス
- TCPでスループットを測定するプログラムを作成しています。受信終了については、通常はソケットのクローズで行いますが、私のプログラムではデータの受信後に返信を行いたいため、ソケットをクローズすることで受信終了とするのは避けたいです。受信終了の合図として、「finish」というメッセージを送信側から受信側に送る方法を考えています。
- 送信側では、「finish」というメッセージを送信し、受信側ではread()メソッドでバイト数を確認しながらデータの受信を続けます。受信データのバイト数の最後から6個を確認し、それが「finish」と一致すれば受信終了とします。
- ただし、受信側での受信終了判定においては、原則としてread()メソッドの戻り値で判定するべきです。受信データに「finish」が含まれる場合でも、read()メソッドの戻り値を確認しながら受信を行うことが推奨されます。このようにすることで、確実な受信終了判定が可能となります。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
UDPは非常に信頼性の低いプロトコルですので、TCPの場合と同様の電文を送受信しても期待したデータを確実に受け取れる保障はありません。 UDPでは、 ・connectに成功しても、相手プロセス(受信側ポート)が存在しているかどうかは不明 ・受信バッファが足りなかった場合に、パケットが破棄されて、エラーかどうかの判別もつかない ・一部パケットをネットワーク上で失っても、分からないことがある のようなことが当然のように発生します。 ですのでUDPでは、(たとえば単なる通知メッセージなどのように)失っても処理に影響を与えないようなもののみを送受信するようにして、 しっかりと送受信したいデータはTCPで送受信するべきだと思います。 性能測定の場合、受信したデータグラムの受信サイズと受信時刻とかをprintするようにして、その時間間隔とサイズを見るぐらいでしょうか。いずれにしても、あまり確実な計測方法は期待しないほうがいいと思います。
その他の回答 (1)
- guccii_txp
- ベストアンサー率60% (3/5)
このままだと最後の"finish"が一回のreadで取得されかった場合に、終了の判定ができいことが発生します。 小さいデータサイズであれば、たいてい一回のreadで全部取得できることが多いのですが、しかしその保障はありません。 "finish"を送る直前にflushすると、"finish"は一回で受信できる可能性はそれなりに高まりますが、間にレイヤ3ハブなどが入ったりすると、やはり保障はありません。 アプリケーションレベルの電文形式を決めて、送受信するのが一般的でしょう。 たとえば、 データ電文 = コマンド("DAT") + データ長 + データ 終了電文 = コマンド("FIN") 終了応答電文 = コマンド("ACK") などと決めておいて、 ・送信側 1.データ電文送信 2.終了電文送信 3.コマンド(終了応答電文)のデータサイズ分(例えば3byte)に達するまで繰り返し受信 ・受信側 1.コマンドのデータサイズ分(例えば3byte)に達するまで繰り返し受信 2.データ電文の場合には、 2-1.データ長をデータ長サイズ分(例えば4byte)に達するまで繰り返し受信 2-2.データをデータ長分に達するまで繰り返し受信 3.終了電文の場合には、終了応答電文を送信して、プログラムを終了する というふうにすれば、確実に終了電文を判定できるでしょう。 終了電文での終了か、切断での終了かをprintしておけば、なお確実に確認できます。 また、データ電文を一定サイズに分割送信してみたり、分割サイズを変えてみたりして、性能にどのような影響がでないのか?でるのか?、また、ネットワーク構成をかえるとどうか?、何でそうなるのか?などを探ってみるともっと面白い性能テストができるかもしれませんね。
お礼
回答ありがとうございます。 TCPとUDPのプログラムを作っています。TCPの方はアドバイスをしていただいたおかげで完成しました。 UDPがうまくできません。UDPもおなじようにやればよいのでしょうか?
お礼
回答ありがとうございます。 送信データをUDPで送信した後、TCPで受信終了させる合図を 送信するという仕組みにしたところ、うまくできました。 アドバイスをしていただき、ありがとうございました。 また、分からないところがあれば質問させていただきますので よろしくお願いします。