QA@IT
«回答へ戻る

回答を投稿

なるほど、わかりました。

ちなみに誤解なきように付け加えておきますがTCPの方が優れていると言っているつもりはありません。信頼性が高いというだけですね。
(動画で過ぎたフレームが再送されても…とか書いていたんですが、長かったので消してしまってたのでTCP推しに見えてしまいましたね。)

たしかにUDPは送信と受信が1対1になりますが、再構築されたパケットロスや順番が違っていて例えばデータ長の部分がおかしくなっている可能性もありますよね。
(元々は送信データが間違っている可能性が…という話でしたが、UDPだと通信内容がおかしいリスクもありますね。詳しい様ですので説明する必要も無さそうですが。)

TCPではたしかに送信と受信は1対1になりません。そこはたしかに考慮漏れてました。
ただ、区切りを明確にしたいのであればソケットを閉じればいいとも思っていました。
たとえば「Webページ」を構成するすべての情報(HTML、CSS、js、画像)を取得するにあたってはブラウザは複数のコネクションを同時に接続して取得します。各ファイルごとにソケットは閉じて次のリソースのために再度接続からやりなおします。これであればファイルという塊をきちんと区別して取得する事ができますね。
(各リソースのHTTPヘッダとボディの間にCRLFという区切り文字があることはもちろん知っています。そういう意味ではHTTPでは区切り文字も使い、レスポンスボディの長さ(ContentLength)もセットされていて、ファイルの区別はソケットを使い回さないことで(ソケットを分ける事で)データを区別するので、固定長以外の簡易な手法は一通りでてきてるかもしれません)

ソケットの使い回しを考えなければUDPのデータグラムの制限よりも大きなデータは送信可能ですし、送りたいだけ送ってしまえばよく、明確に分けたいデータを送る時が来たらそれは別のソケットを使う…とすれば塊は表現できるとおもいます。
(今回のコードでは明確な終了データらしきものを送信させましたが、TCPで使い回しを考えないケースではrecvを呼びつづけて、最初にrecv長が0になったらデータが最後まで来た(FINの後である)としてソケットを閉じるケースが多いと思います)

塊はそれで表現できますからセットされているデータ長が正しいかどうかも比較できますので元の質問にあったような設定されているデータ長が誤っている場合も対処できます。
(実際HTTPはContentLengthが正しいかどうかチェックされることがありますね)
クロスチェックとしてチェックデータつけたい場合も固定長なら最後でも平気そうですね。
(最初はWebSocketのフレームとか別の事と思ってましたもので…)

実際にはデータの設計などが決まってから適切なものを選択する事になると思います(どれが正しいという事はないと思います)が、参考になれば幸いです。

なるほど、わかりました。

ちなみに誤解なきように付け加えておきますがTCPの方が優れていると言っているつもりはありません。信頼性が高いというだけですね。
(動画で過ぎたフレームが再送されても…とか書いていたんですが、長かったので消してしまってたのでTCP推しに見えてしまいましたね。)

たしかにUDPは送信と受信が1対1になりますが、再構築されたパケットロスや順番が違っていて例えばデータ長の部分がおかしくなっている可能性もありますよね。
(元々は送信データが間違っている可能性が…という話でしたが、UDPだと通信内容がおかしいリスクもありますね。詳しい様ですので説明する必要も無さそうですが。)

TCPではたしかに送信と受信は1対1になりません。そこはたしかに考慮漏れてました。
ただ、区切りを明確にしたいのであればソケットを閉じればいいとも思っていました。
たとえば「Webページ」を構成するすべての情報(HTML、CSS、js、画像)を取得するにあたってはブラウザは複数のコネクションを同時に接続して取得します。各ファイルごとにソケットは閉じて次のリソースのために再度接続からやりなおします。これであればファイルという塊をきちんと区別して取得する事ができますね。
(各リソースのHTTPヘッダとボディの間にCRLFという区切り文字があることはもちろん知っています。そういう意味ではHTTPでは区切り文字も使い、レスポンスボディの長さ(ContentLength)もセットされていて、ファイルの区別はソケットを使い回さないことで(ソケットを分ける事で)データを区別するので、固定長以外の簡易な手法は一通りでてきてるかもしれません)

ソケットの使い回しを考えなければUDPのデータグラムの制限よりも大きなデータは送信可能ですし、送りたいだけ送ってしまえばよく、明確に分けたいデータを送る時が来たらそれは別のソケットを使う…とすれば塊は表現できるとおもいます。
(今回のコードでは明確な終了データらしきものを送信させましたが、TCPで使い回しを考えないケースではrecvを呼びつづけて、最初にrecv長が0になったらデータが最後まで来た(FINの後である)としてソケットを閉じるケースが多いと思います)

塊はそれで表現できますからセットされているデータ長が正しいかどうかも比較できますので元の質問にあったような設定されているデータ長が誤っている場合も対処できます。
(実際HTTPはContentLengthが正しいかどうかチェックされることがありますね)
クロスチェックとしてチェックデータつけたい場合も固定長なら最後でも平気そうですね。
(最初はWebSocketのフレームとか別の事と思ってましたもので…)

実際にはデータの設計などが決まってから適切なものを選択する事になると思います(どれが正しいという事はないと思います)が、参考になれば幸いです。