
現在Winsockを用いてTCP/IPメッセージ通信を行うプログラムを作成
しています。
メッセージはヌル文字区切りで送信され、ヌルが発見されると一つの
メッセージの終わりということにしてあります。
このメッセージを時間ウェイトを入れずに連続して送信すると受信側で
正常にデータが受信できず、送信したデータの一部しか受信できません。
ある程度の時間ウェイトを入れてやることで正常に送受信できるように
なります。
受信側の処理において、recvでデータを取得した後にメッセージパーズ
処理を入れているのですがそれほど重い処理でもありません。いろいろ
調べたのですが正常に送受信するときとしないときの違いが連続送信時
に入れる時間ウェイトにあるということしかわかっておりません。
これがTCP/IPの特性なのか私の開発環境(PC・ネットワーク)に起因する
ものなのかがわかりません。どなたかこういった現象についてご経験を
お持ちの方がおられましたらご教授願いたいと思っております。
以上
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
>メッセージはヌル文字区切りで送信され、ヌルが発見されると一つの
>メッセージの終わりということにしてあります。
TCP/IPも含めて、シリアル通信上でこの仕様はあまりよくありません。
通信においては「受信データBYTE数は、それを受信する前にわかって
いる」事が理想となります。つまり可能ならば文字列などの可変長
データは「データ長」+「データ」の順で送信するのが理想となり
ます。この仕様ならデータ部の受信途中で途切れても、残りの数が
自明となります。もちろんデータの先頭を示すシグネチャもあった
方が良いでしょう。
この回答への補足
送信時に送信データサイズ情報も一緒に送るのが理想とおっしゃるのは
確かにそのとおりですね。最初はその方針でした。ただソケットの特性
について知らない部分があったのでこの方法でも原理的には問題ないの
ではと思っていました。
一区切りの送信データを受け取ってからその内容をパーズするという方針
が可能であれば受信側での状態遷移を設計する手間が省けるのでやってみ
たんですがソケットの特性の前に見事にはまりました。

No.2
- 回答日時:
おはようございます。
1回の受信で全データを取得できると思って失敗した事のある者です。
私の場合は、PC間に配置されたルータが送信データ長を少なく絞った為、
受信データが寸断されていました。
HTTP通信であった為、受信側では送信データ長が判断できませんでした。
送信データ長が受信側であらかじめ解っているのでしたら送信データ長まで受信を続ける、
送信データ長が解らない場合はデータ最後にエンドマークを入れ、
それを受信できるまで受信を続ける方法はどうでしょうか?
ご参考までに。
この回答への補足
ご回答ありがとうございます。
1回の受信ですべてのデータが取得できると思い込んではまっているわけ
ではありません。時間ウェイトなしでの連続送信時に送信しただけのデータ
が必ずしも受け取れないという問題でした。
No.1
- 回答日時:
(送信時の)Socktの特性です。
問題はウエイトではなくデータ長にあります。
プログラムの処理能力と物理層の転送能力にはギャップがありますので、当然IP層は送受信用のバッファを持っています。
ウエイトを入れる事で送信バッファが吐き出されバッファに余裕が出来るからIP層がデータの全てを受け取れる状態になっているのだと推測します。
バッファにはもちろん限りがありますので連続送信や長いデータを送る場合に、データの全てが一度に送れる訳ではありません。
実際に送信できたバイト数はsendのリターン値を見れば分かります。
その上で、全てのデータを送り終えるまでポーリングすれば良いです。
この回答への補足
やはりその辺の特性が理由なようですね。大変参考になりました。
なんというかつまり、ある程度のサイズのデータをがしがし送っても
うまくできないものなんですね。
ちなみにsend処理ではsendの返り値を加算して目的の送信データ長
に達するまでループするようにはしてあります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# TCP/IP通信時のサーバーからの受信 2 2022/11/23 09:11
- その他(コンピューター・テクノロジー) 「プロトコル」の定義について 5 2023/04/16 13:13
- docomo(ドコモ) +メッセージの送受信。 au(uq mobile)のデータ回線でdocomoの電話番号の+メッセージ 2 2022/09/14 16:09
- UNIX・Linux Ubuntuサーバーでメールを受信できない 7 2022/08/23 20:55
- Gmail gmail から docomo メールに送信できません 4 2022/06/25 00:41
- ネットワーク OSI参照モデルの各層の役割がわかりません。 3 2023/04/21 21:12
- その他(メールソフト・メールサービス) メールサーバーは「PC側がメールをDL済みか否か?」を何を以て感知するのか? 2 2022/12/20 14:56
- その他(メールソフト・メールサービス) サンダーバードでメールが受信されない 10 2022/03/24 17:00
- Outlook(アウトルック) メール送信できない 3 2022/07/20 09:07
- ガラケー・PHS 携帯電話の居場所信号の発信タイミング 3 2022/07/27 14:39
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
RS-232Cでバイナリデータを受信...
-
Linuxでのシリアル通信について...
-
write関数でEAGAINのエラー発生...
-
WriteFile()でのデータ送信がで...
-
「スイッチングハブのバッファ...
-
ReadFile(GPSとの通信)Win7で...
-
winsockの動作について。
-
WinsockAPIのrecvfromの受信デ...
-
rs232cでの受信データ(mscomm)...
-
C# シリアル通信でデータ受信...
-
C#で通信処理。応答がない場合...
-
再現性の無いバグ
-
Access Violationについて
-
WSH(VBScript)でアプリケーショ...
-
Macターミナルで実行中のプログ...
-
SetWindowPosについて
-
vba listviewにおけるtextのAli...
-
複数スレッドを動作させるのに...
-
SQLの速度をあげるには・・・
-
オフスクリーンサーフェスへの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
「スイッチングハブのバッファ...
-
winsockでソケット通信の開発を...
-
シリアル通信の出力バッファと...
-
WriteFile()でのデータ送信がで...
-
Linuxでのシリアル通信について...
-
WinsockAPIのrecvfromの受信デ...
-
socket: recvはいつ,どれだけ...
-
SerialPortのDataReceivedイベ...
-
ClearCommError呼び出し時のCE_...
-
TCPでの非同期型select関数につ...
-
シリアルポート通信
-
シリアル通信 大きいサイズの...
-
winsockの動作について。
-
ソケット通信内 read関数について
-
COMポートの同時オープン同時読...
-
SocketのSend関数でのCLOSEの検...
-
waveIn、waveOutでの音声録音・...
-
write関数でEAGAINのエラー発生...
-
rs232cでの受信データ(mscomm)...
おすすめ情報