recv関数のデータ長 – プログラミング – Home

通知
すべてクリア

[解決済] recv関数のデータ長


まみ
 まみ
(@まみ)
ゲスト
結合: 17年前
投稿: 10
Topic starter  

おはようございます。

ソケット通信のrecv()という関数についての質問です。
相手から、50バイトのデータが送られた時に、recvが返すデータ長が
50未満になることはなるのでしょうか?
(パケットが分割されて送られてくることはあるのでしょうか?)
ある場合、それはどんな時(どんな理由)でしょうか?

VisualC++6.0, WindowsXP, MFC, Dialog の環境

よろしくお願いします。


引用未解決
トピックタグ
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

同期モードの場合は50Byte受信するまで関数から戻りません。

非同期モードの場合は、コード上「ありえる」コードになって
いなければなりません。
まぁ、現実的にはほとんどありませんが。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

TCP ならごく普通に「なる」
通信が輻輳しているときとか
クライアントマシンが忙しいときとか、逆にお手すきな場合とか

TCP ならそれはごく正常な動作なので問題なし
再度 read することで 20+30 バイトなどのように合計 50 になるはずだよ

> パケットが
TCP はストリームなので、パケットという概念は無い(考えちゃダメ)


返信引用
まみ
 まみ
(@まみ)
ゲスト
結合: 17年前
投稿: 10
Topic starter  

>非同期モードの場合は、コード上「ありえる」コードになって
>いなければなりません。

仲澤さん、tetrapodさん お返事ありがとうございます。

予想より少なかったら、recvしてトータル数があうように
コーディングすれば良いわけですね。

>TCP はストリームなので、パケットという概念は無い

こちらの意味がわからないので、詳しく教えていただけませんか?


返信引用
通行人
 通行人
(@通行人)
ゲスト
結合: 23年前
投稿: 11
 

ネットワーク層(IPとか)やトランスポート層(TCPとか)のネットワークレイヤーにつ
いて調べてみるといいんじゃないでしょうか。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

ストリームの概念が理解できれば、パケットの概念が端からないのは理解できるのでは
ないかと思います。ストリームの場合、垂れ流し的に流れてくるイメージだと思うので
流れてくるデータに対にして何処までが一塊のデータなのかを認識するのは取り出す方の
責任で行なうのが普通なんではないかと。

パケットの場合、受信する側がパケットで分割されてくる事を意識して
パケット分割されてきた時はパケットの内容を連結して処理する必要があるわけで
ストリームでこれを意識して扱うのは変と言う話かな。


返信引用
ライト
 ライト
(@ライト)
ゲスト
結合: 22年前
投稿: 5
 

ああ


返信引用
まみ
 まみ
(@まみ)
ゲスト
結合: 17年前
投稿: 10
Topic starter  

おはようございます。

皆様、お返事ありがとうございます。
難しくてよくわからないのですけど、ストリームだと分割されても
順番は 1,2,3 と送られてきて、パケットは順番が必ずしも 1,2,3 にならない?
という意味でしょうか?


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

概念の層が違うわけで 通行人 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 ストリームとは でぐぐってみよう


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

10+10+70 だな・・・10バイト欠落しちゃうよ orz


返信引用
まみ
 まみ
(@まみ)
ゲスト
結合: 17年前
投稿: 10
Topic starter  

通行人さん、ぱっちょさん

ありがとうございます。

tetrapodさん

ご丁寧に教えて頂きありがとうございます。
良く理解できました。
シーケンス番号があるんですネ
もう少し詳しく調べてみます。

> 10+10+70 だな・・・10バイト欠落しちゃうよ orz

頭の良い人でも足し算間違えるんデスネ (^^)

皆様、ありがとうございました。m(__)m


返信引用
シソ
 シソ
(@シソ)
ゲスト
結合: 17年前
投稿: 2
 

ああ


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました