現在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で質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
許せない心理テスト
私は「あなたの目の前にケーキがあります。ろうそくは何本刺さっていますか」と言われ「12本」と答えたら…
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
TCP/IP のパケットの分断と結合について
UNIX・Linux
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
Linuxでのシリアル通信について...
-
ClearCommError呼び出し時のCE_...
-
rs232cでの受信データ(mscomm)...
-
mscommの受信バッファ異常について
-
socket: recvはいつ,どれだけ...
-
WinsockAPIのrecvfromの受信デ...
-
winsockでソケット通信の開発を...
-
【CAsyncSocket::OnReceive()呼...
-
シリアル通信の出力バッファと...
-
シリアルポート通信
-
winsockの動作について。
-
Macターミナルで実行中のプログ...
-
3のつく数字と3の倍数のみを表...
-
VBSの処理中一旦処理を止めて再...
-
vba listviewにおけるtextのAli...
-
緯度、経度の 10進法と 60進法...
-
「ヒープサイズの設定」て何?
-
VBSで応答不要のメッセージボッ...
-
VB6で10進数を32進数に変換する...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
WriteFile()でのデータ送信がで...
-
winsockでソケット通信の開発を...
-
socket: recvはいつ,どれだけ...
-
シリアル通信の出力バッファと...
-
「スイッチングハブのバッファ...
-
SocketのSend関数でのCLOSEの検...
-
Connection reset by peer
-
WaitForMultipleObjects関数の...
-
RS232C通信(PC⇔PLC)
-
VB2005でWin32APIを用いてRS-23...
-
Linuxでのシリアル通信について...
-
UDP処理のエラーについて
-
シリアルポート通信
-
ソケット通信内 read関数について
-
TCP/IP通信プログラミングにお...
-
rs232cでの受信データ(mscomm)...
-
write関数でEAGAINのエラー発生...
-
シリアル通信ができません
-
【CAsyncSocket::OnReceive()呼...
おすすめ情報