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

現在Winsockを用いてTCP/IPメッセージ通信を行うプログラムを作成
しています。

メッセージはヌル文字区切りで送信され、ヌルが発見されると一つの
メッセージの終わりということにしてあります。

このメッセージを時間ウェイトを入れずに連続して送信すると受信側で
正常にデータが受信できず、送信したデータの一部しか受信できません。
ある程度の時間ウェイトを入れてやることで正常に送受信できるように
なります。

受信側の処理において、recvでデータを取得した後にメッセージパーズ
処理を入れているのですがそれほど重い処理でもありません。いろいろ
調べたのですが正常に送受信するときとしないときの違いが連続送信時
に入れる時間ウェイトにあるということしかわかっておりません。

これがTCP/IPの特性なのか私の開発環境(PC・ネットワーク)に起因する
ものなのかがわかりません。どなたかこういった現象についてご経験を
お持ちの方がおられましたらご教授願いたいと思っております。

以上

A 回答 (3件)

(送信時の)Socktの特性です。


問題はウエイトではなくデータ長にあります。

プログラムの処理能力と物理層の転送能力にはギャップがありますので、当然IP層は送受信用のバッファを持っています。
ウエイトを入れる事で送信バッファが吐き出されバッファに余裕が出来るからIP層がデータの全てを受け取れる状態になっているのだと推測します。

バッファにはもちろん限りがありますので連続送信や長いデータを送る場合に、データの全てが一度に送れる訳ではありません。
実際に送信できたバイト数はsendのリターン値を見れば分かります。
その上で、全てのデータを送り終えるまでポーリングすれば良いです。

この回答への補足

やはりその辺の特性が理由なようですね。大変参考になりました。

なんというかつまり、ある程度のサイズのデータをがしがし送っても
うまくできないものなんですね。

ちなみにsend処理ではsendの返り値を加算して目的の送信データ長
に達するまでループするようにはしてあります。

補足日時:2008/09/14 01:55
    • good
    • 0
この回答へのお礼

どうやらこれのようです。
http://www.kt.rim.or.jp/~ksk/wskfaq-ja/intermedi …

お礼日時:2008/09/14 03:05

おはようございます。



1回の受信で全データを取得できると思って失敗した事のある者です。
私の場合は、PC間に配置されたルータが送信データ長を少なく絞った為、
受信データが寸断されていました。
HTTP通信であった為、受信側では送信データ長が判断できませんでした。

送信データ長が受信側であらかじめ解っているのでしたら送信データ長まで受信を続ける、
送信データ長が解らない場合はデータ最後にエンドマークを入れ、
それを受信できるまで受信を続ける方法はどうでしょうか?

ご参考までに。

この回答への補足

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

1回の受信ですべてのデータが取得できると思い込んではまっているわけ
ではありません。時間ウェイトなしでの連続送信時に送信しただけのデータ
が必ずしも受け取れないという問題でした。

補足日時:2008/09/14 02:10
    • good
    • 0

>メッセージはヌル文字区切りで送信され、ヌルが発見されると一つの


>メッセージの終わりということにしてあります。

TCP/IPも含めて、シリアル通信上でこの仕様はあまりよくありません。
通信においては「受信データBYTE数は、それを受信する前にわかって
いる」事が理想となります。つまり可能ならば文字列などの可変長
データは「データ長」+「データ」の順で送信するのが理想となり
ます。この仕様ならデータ部の受信途中で途切れても、残りの数が
自明となります。もちろんデータの先頭を示すシグネチャもあった
方が良いでしょう。

この回答への補足

送信時に送信データサイズ情報も一緒に送るのが理想とおっしゃるのは
確かにそのとおりですね。最初はその方針でした。ただソケットの特性
について知らない部分があったのでこの方法でも原理的には問題ないの
ではと思っていました。

一区切りの送信データを受け取ってからその内容をパーズするという方針
が可能であれば受信側での状態遷移を設計する手間が省けるのでやってみ
たんですがソケットの特性の前に見事にはまりました。

補足日時:2008/09/14 02:01
    • good
    • 0

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