おはようございます。
ソケット通信のrecv()という関数についての質問です。
相手から、50バイトのデータが送られた時に、recvが返すデータ長が
50未満になることはなるのでしょうか?
(パケットが分割されて送られてくることはあるのでしょうか?)
ある場合、それはどんな時(どんな理由)でしょうか?
VisualC++6.0, WindowsXP, MFC, Dialog の環境
よろしくお願いします。
同期モードの場合は50Byte受信するまで関数から戻りません。
非同期モードの場合は、コード上「ありえる」コードになって
いなければなりません。
まぁ、現実的にはほとんどありませんが。
TCP ならごく普通に「なる」
通信が輻輳しているときとか
クライアントマシンが忙しいときとか、逆にお手すきな場合とか
TCP ならそれはごく正常な動作なので問題なし
再度 read することで 20+30 バイトなどのように合計 50 になるはずだよ
> パケットが
TCP はストリームなので、パケットという概念は無い(考えちゃダメ)
>非同期モードの場合は、コード上「ありえる」コードになって
>いなければなりません。
仲澤さん、tetrapodさん お返事ありがとうございます。
予想より少なかったら、recvしてトータル数があうように
コーディングすれば良いわけですね。
>TCP はストリームなので、パケットという概念は無い
こちらの意味がわからないので、詳しく教えていただけませんか?
ネットワーク層(IPとか)やトランスポート層(TCPとか)のネットワークレイヤーにつ
いて調べてみるといいんじゃないでしょうか。
ストリームの概念が理解できれば、パケットの概念が端からないのは理解できるのでは
ないかと思います。ストリームの場合、垂れ流し的に流れてくるイメージだと思うので
流れてくるデータに対にして何処までが一塊のデータなのかを認識するのは取り出す方の
責任で行なうのが普通なんではないかと。
パケットの場合、受信する側がパケットで分割されてくる事を意識して
パケット分割されてきた時はパケットの内容を連結して処理する必要があるわけで
ストリームでこれを意識して扱うのは変と言う話かな。
ああ
おはようございます。
皆様、お返事ありがとうございます。
難しくてよくわからないのですけど、ストリームだと分割されても
順番は 1,2,3 と送られてきて、パケットは順番が必ずしも 1,2,3 にならない?
という意味でしょうか?
概念の層が違うわけで 通行人 2008/03/03(月) 12:00:06 氏のコメントどおり
ネットワークの層構造について理解しておくことを推奨するわけだが
UDP では話は違うのでまず除外して
通信の上位層での概念を言うなら
ストリームとは:データの流れ、ないしは、流れてくるデータ
ファイルを1バイト単位で読み書きできる形式で取り扱う=ストリーム、つうことだ
TCP=ネットワークからの通信を1バイト単位で読み書きできる形式で取り扱う
=ストリーム、つうことなわけ。
(ファイルは seek できるが、通信は seek できないという違いは有るけど)
これに対して、別の層(下位層)での概念では
・ファイルはディスク上に置いてある
・ディスクは「セクター」という単位に分割されている
・だからOS/デバイスドライバーはセクター単位での読み書きを行う
ここでは「入出力単位(≒パケット」)という概念が出てくる
ネットワークでもエラー訂正単位とか再試行単位とか MTU とか、そーいう
「パケット」の概念が有るわけだが、それはOS/デバイスドライバの仕事であって
TCP で入出力を行う場合、そーいう低レベル層の詳細は隠されているため
プログラマは一切気にせず1バイト単位で入出力してよい
(むしろ、そういう詳細を気にしてはいけない)
ということ。
> 順番は 1,2,3 と送られてきて、パケットは順番が必ずしも 1,2,3 にならない?
結果的にそうなるわけだ
ネットワーク上の通信データは、分割されたり順序が入れ替わったり欠落したりする
TCP レベルで入出力する場合には、そういう瑣末なことの詳細はOSが面倒を見るため
我々一般プログラマが組むレベルのプログラムでは結果的に 1,2,3 が得られるし
1,2,3 と送れば相手側でもそれをこの順に受け取ることが出来るということ。
TCP では
送信側が 50 + 40 バイトと send() した場合であっても
受信側が 50 + 40 バイトと recv() される保証は一切無い
受信側で保証されているのは
「送信側が送ったデータが一式、欠落無く順序が入れ替わらず受け取れる」
ことだけ。
90 バイトを一気に受け取る可能性もあるし
80+10 バイトのように分割される可能性もあるし
10+10+60 バイトのように分割される場合もある
TCP ストリームとは でぐぐってみよう
10+10+70 だな・・・10バイト欠落しちゃうよ orz
通行人さん、ぱっちょさん
ありがとうございます。
tetrapodさん
ご丁寧に教えて頂きありがとうございます。
良く理解できました。
シーケンス番号があるんですネ
もう少し詳しく調べてみます。
> 10+10+70 だな・・・10バイト欠落しちゃうよ orz
頭の良い人でも足し算間違えるんデスネ (^^)
皆様、ありがとうございました。m(__)m
ああ