プロが教える店舗&オフィスのセキュリティ対策術

linux で socket を使ってプログラムを作っております。
パケットの頭に、どんな種類のパケットかの情報を入れ、それに続く部分にデータを入れて送っております。受信側では、届いたパケットの頭の情報を見て必要な処理を行う、という流れになっております。
ところが、時々、次のような現象が発生して困っております。

・送信側で一回のsendで送ったはずのデータが受信側では一回のrecvで届かず、二回のrecvで届く。
・送信側では二回のsendで送ったつもりなのに、受信側では一回のrecvで2つのパケットが結合したデータが届く。

これはsendとrecvでは普通に起こると想定しなければならない現象なのでしょうか?
それとも、linuxマシンの設定に問題があるのでしょうか?

A 回答 (3件)

>・送信側で一回のsendで送ったはずのデータが受信側では一回のrecvで届かず、二回のrecvで届く。


>・送信側では二回のsendで送ったつもりなのに、受信側では一回のrecvで2つのパケットが結合したデータが届く。

TCPは「ストリーム」なのでそういう動作をしても不思議ではない。
ということになります。

>それとも、linuxマシンの設定に問題があるのでしょうか?

Windowsでも普通に発生します。

http://www.ne.jp/asahi/hishidama/home/tech/socke …
send(送信)、recv(受信)や
http://www.ne.jp/asahi/hishidama/home/tech/socke …
等を参照…でしょうか。
# 他にもそういった解説をしているページはあるでしょう。
http://rgv250.dyndns.org/socket.htm

http://hp.vector.co.jp/authors/VA019876/sokrpg/d …
の「たまに、受信したレコードの最後が途中で切れていることがあります。どうしてでしょうか? 」とか…

この回答への補足

ご回答有難うございました。
お礼を書き忘れましたので、こちらに書かせていtだきました

補足日時:2011/10/17 22:08
    • good
    • 0
この回答へのお礼

なうほど、TCP/IPの仕様なんですね。
こういう事も起こりうるとして作らないといけないのですね。

お礼日時:2011/10/17 22:00

それはTCPによる通信の特徴です。



TCPはバイトストリーム型のプロトコルですので、
流れてくるバイト列には一切の区切りがありません。

100バイト×10回で送信しても、500バイト×2回で送信しても、
あるいは999バイトと1バイトを連続して送信しても、
TCPにおいては同じ意味になります。

同様に1000バイトを受信する側も、
1000バイト×1回のrecvになることも、
500バイト×2回のrecvになることもあります。

このようなメッセージの境界を保証しないTCPの特性に対し、
メッセージ境界を保証するSCTPのようなプロトコルもあります。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。

お礼日時:2011/10/17 22:09

>ところが、時々、次のような現象が発生して困っております。


>これはsendとrecvでは普通に起こると想定しなければならない現象なのでしょうか?

普通に起こる現象です。

sendとrecvは「sendとrecvが1対1になる保証はない」のです。

1000バイトsendしたら、1、1、998の3回に分けて届くかも知れないし、2000バイト送って1000バイト送ってと、3000バイトを2回にわけて送ったら、1450、1450、100と、3回に分かれて届くかも知れません。

なので、recvは「何回、何十回に分かれて届いても大丈夫なように受信」しなければなりません、パケットがピッタリサイズで届くとは限らないので、バッファリング処理も要ります。

受信処理では、途中で届かなくなった場合のタイムアウト処理も要ります。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。
今後は、こう言う事も想定して、おきたいとおもいます。

お礼日時:2011/10/17 22:08

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

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A