アプリ版:「スタンプのみでお礼する」機能のリリースについて

Winsock2を使ってソケットプログラミングをするため通信プロトコルを考えています。そこでソケットの挙動について疑問があります。

sendを複数回使って以下のバイト数のデータを送信したとします。
1.3byte送信[AAA]
2.5byte送信[BBBBB]
3.3byte送信[CCC]

このとき正常に通信ができたときは受信側では1~3回のrecvによって
[AAABBBBBCCC]
というデータが受信できると思います。ここまではいいのですが、疑問があるのは送受信に異常があった場合です。

1.send単位で欠落(再度connectの必要なし)。損失受信データ例[AAACCC]、[BBBBBCCC]
2.TCP上での送信パケット単位で欠落(再度connectの必要なし)。損失データ例[AAABB]
3.send単位で欠落して以後は全て欠落(再度connect必要あり)。損失データ例[AAABBBBB]、[AAA]
4.TCPのパケット単位で欠落して以後は全て欠落(再度connect必要あり)。損失データ例[AAABB]

おそらくこれらのいずれかの方法でデータが欠落することになるかと思います。データの再送信をするのであればconnectが必要になるのかという点も分かりません。
ソケットがcloseになったという理由によるデータ欠落であれば4番になるかと思いますが。。。@FreeDのようにドーマントに入るようなネットワークの場合単純にcloseを期待することもできないような気がしますし。。。

どなたか教えていただけないでしょうか?よろしくお願いします。

A 回答 (3件)

基本的にTCP自体が


チェックサム等をもち信頼性のあるプロトコルです。

特に1(send単位で欠落)等は途中でデータが損失していますが、
ひとつのパケットに対してシーケンス番号を持っている為
その時点でコネクションロストします。
1~4いずれにしてもデータがおかしい場合
再度connectの必要があります。

あるとするなら
3.send単位で欠落して以後は全て欠落(再度connect必要あり)。損失データ例[AAABBBBB]、[AAA]
ただしsend単位ではなくパケット単位です
例えばsendで5Mぐらいのデータを送ろうとしても内部で1024バイトずつに
分割されていたりします。(recvでも1024ずつ受け取ります)

参考URL:http://akademeia.info/main/lecture2/hyoujyunn_tc …

この回答への補足

4番の例になるということですね。自分の中では1番可能性がありそうだと思っていたものです。参考URLもまだ詳しくは見ていませんが役に立ちそうです。ありがとうございます。

補足日時:2005/02/10 02:03
    • good
    • 0

すいません。

4ですね。
ただ5バイトの文字列(BBBBB)が2つのパケット(BBとBBB)になることは
基本的にはありませんが
勿論プログラム的に必ず5バイトが1パケットで送られることを
前提とするのはよくないです。

1パケットの最大サイズ
MTU(Max Transfer Unit)は
Windowsならレジストリに設定されていると
思います。
ちなみにWin2kのデフォルトは1024らしいです。
(だからsendが1024ずつに分割されたのかと今納得、、)

参考URL:http://www.janis.or.jp/adsl/tuneup/tcp_tune.html
    • good
    • 0

アプリケーションから見た場合、sendが正常なら、ちゃんと受信できている。

としか判断できません。
完全にブラックボックスの世界です。

なので、sendで送ったバイト数と戻り値が異なっていれば、socketをshutdown & closesocketして、再度、connectする必要があります。

この回答への補足

>sendで送ったバイト数と戻り値が異なっていれば、socketをshutdown & closesocketして、再度、connectする必要があります。

MSDNにはsend関数の解説として
----------------
宣言
int send(SOCKET s,const char FAR *buf,int len,int flags);

戻り値
If no error occurs, send returns the total number of bytes sent, which can be less than the number indicated by len for nonblocking sockets.
----------------
と書かれています。現在使おうと考えているソケットは非ブロッキングです。そのため戻り値では単純にチェックできません。プログラム上でタイムアウトを設定して時間内に指定したバイト数送信できなければcloseと考えるということになりそうですね。

補足日時:2005/02/10 02:03
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!