
linux で socket を使ってプログラムを作っております。
パケットの頭に、どんな種類のパケットかの情報を入れ、それに続く部分にデータを入れて送っております。受信側では、届いたパケットの頭の情報を見て必要な処理を行う、という流れになっております。
ところが、時々、次のような現象が発生して困っております。
・送信側で一回のsendで送ったはずのデータが受信側では一回のrecvで届かず、二回のrecvで届く。
・送信側では二回のsendで送ったつもりなのに、受信側では一回のrecvで2つのパケットが結合したデータが届く。
これはsendとrecvでは普通に起こると想定しなければならない現象なのでしょうか?
それとも、linuxマシンの設定に問題があるのでしょうか?
No.1ベストアンサー
- 回答日時:
>・送信側で一回の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 …
の「たまに、受信したレコードの最後が途中で切れていることがあります。どうしてでしょうか? 」とか…
No.3
- 回答日時:
それはTCPによる通信の特徴です。
TCPはバイトストリーム型のプロトコルですので、
流れてくるバイト列には一切の区切りがありません。
100バイト×10回で送信しても、500バイト×2回で送信しても、
あるいは999バイトと1バイトを連続して送信しても、
TCPにおいては同じ意味になります。
同様に1000バイトを受信する側も、
1000バイト×1回のrecvになることも、
500バイト×2回のrecvになることもあります。
このようなメッセージの境界を保証しないTCPの特性に対し、
メッセージ境界を保証するSCTPのようなプロトコルもあります。
No.2
- 回答日時:
>ところが、時々、次のような現象が発生して困っております。
>これはsendとrecvでは普通に起こると想定しなければならない現象なのでしょうか?
普通に起こる現象です。
sendとrecvは「sendとrecvが1対1になる保証はない」のです。
1000バイトsendしたら、1、1、998の3回に分けて届くかも知れないし、2000バイト送って1000バイト送ってと、3000バイトを2回にわけて送ったら、1450、1450、100と、3回に分かれて届くかも知れません。
なので、recvは「何回、何十回に分かれて届いても大丈夫なように受信」しなければなりません、パケットがピッタリサイズで届くとは限らないので、バッファリング処理も要ります。
受信処理では、途中で届かなくなった場合のタイムアウト処理も要ります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
ネットワーク切断を検出するには?
C言語・C++・C#
-
socket: recvはいつ,どれだけ受け取るのか?
C言語・C++・C#
-
UDPパケットの分割について
その他(インターネット接続・インフラ)
-
-
4
recv関数の受信結果について
C言語・C++・C#
-
5
ソケット通信 同じポート番号でn対1はできない?
C言語・C++・C#
-
6
TCP/IP通信時のパケット分割について、パケットがMTU以下なのになぜ分割されるの?
UNIX・Linux
-
7
ソケットのrecvの戻り値が0
C言語・C++・C#
-
8
C# ソケット通信でデータ受信時の欠損について
C言語・C++・C#
-
9
画面を強制的に再描画させる方法
C言語・C++・C#
-
10
ソケットのクローズについて
C言語・C++・C#
-
11
winsockの非同期処理について
C言語・C++・C#
-
12
recv関数の戻り値について
C言語・C++・C#
-
13
IG、ACC、+B、ILL
国産バイク
-
14
UDP通信する時に、相手にどうやって自分のポート番号を教える?
Java
-
15
Socket通信の0バイト受信について
Java
-
16
<unistd.h>をVisualStudioでつかえるようにする
C言語・C++・C#
-
17
CloseとDisposeの違い
Visual Basic(VBA)
-
18
UDP通信におけるbind関数について
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Outlookの「受信日時」「件名」...
-
Windows Mobile6.1 メール受信...
-
TCP/IP のパケットの分断と結合...
-
VC++メッセージの送受信につい...
-
シリアル通信時のデータ受信方法
-
ASP.NET C#でPOST受信
-
recv関数の戻り値について
-
パソコンに詳しい方教えて下さ...
-
バッチファイルでディレクトリ...
-
ARCserveの復元方法
-
Windows上のファイル操作の履歴...
-
別のフォルダにファイルを移動...
-
隠しファイルとZip圧縮について
-
Zipファイルをエクセルに指定変...
-
指定ファイルをFTPで自動アップ...
-
Windows 7 標準のZip解凍が出来...
-
ipadで社内ネットワークに接続
-
java.lang.NumberFormatExcepti...
-
グローバルIPアドレスを取得し...
-
Lhaplusが発したと、みられるエ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Outlookの「受信日時」「件名」...
-
TCP/IP のパケットの分断と結合...
-
Outlookの「受信日時」「送信者...
-
UDP受信時の通信異常検知について
-
CRC-CCITTに関しての仕様とサン...
-
ASP.NET C#でPOST受信
-
recv関数の戻り値について
-
VB2010で、シリアル通信の方法...
-
HPのメールフォームについて
-
アンテナってあるでしょ?あれC...
-
シリアル通信時のデータ受信方法
-
赤外線通信
-
C#にてCTI。RS232Cの受信と送信...
-
受信処理の終了条件
-
PICを用いた赤外線通信
-
DHCPOFFERの受信について
-
VB2005でTCP/IPソケット通信で...
-
.NetのTimerについて
-
文字化け
-
winsockを使ったTCP及びUDP通信...
おすすめ情報