こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Winsockで1460Byte以降のデータが細切れに

度々お世話になってます。
VB6.0、Winsockで、チャットプログラムを作っているのですが・・・

20文字のヘッダーで、処理が識別されるプログラムを作っているんですが、1460バイトを超えるデータが途中で切れて、ヘッダー無しの状態になって、処理を識別できないんですが・・・。

1460という数字は、DataArrivalのbytesTotalで調べたのですが、制御コード(のバイト数)とか、決まっているのでしょうか?

Send メソッドで通信する場合、一度に送るサイズを1460バイトにしたいのですが、サーバ←→クライアント間で、自力で作るしかないですかね・・・?

データを分割して、配列 myArray(partNum) にする。 先ほどと同じ処理のACKをクライアントが受信したら、partNumを+1して、データを送信。

client.SendData <処理A> 1:○○
server.GetData <A> 1:○○
server.SendData <A> 1:ACK
client.SendData <A> 2:●●



client.SendData <A> 9999:End

方向性はあってますかね?

なにか、楽な方法ありませんか?(汗)

cf.
http://bbs.wince.ne.jp/ch1/mqbbs.cgi?MODE=MSG&NUM=5156&FILE=bbs.log.51
http://bbs.wince.ne.jp/ch1/mqbbs.cgi?&FILE=bbs.log.51&MODE=MSG&NUM=5161

投稿日時 - 2005-07-28 13:44:12

QNo.1543941

すぐに回答ほしいです

質問者が選んだベストアンサー

>途中で切れて、ヘッダー無しの状態になって、処理を識別できないんですが・・・。

TCPはそういうものなんですが・・・(^^;

WinSockコントロールでいうところのDataArrivalイベントにおいて、クライアントから送られたデータが1回(のイベント)で処理できるという保証はありません。

極端な話「こんにちわ」と送っても「こん」「にちわ」と届くかもしれない、ということです。(順序は保証されているので、繋げれば必ず「こんにちわ」になります)

>1460という数字は、DataArrivalのbytesTotalで調べたのですが

MTUとかRWINとか、ADSL初期の頃話題になった「ウインドウサイズ」という言葉がわかりやすいと思います。
簡単に言うと、そのI/F(LANカードとか)がどのくらいのパケットを一度で受け取れるか、を示します。これは変更可能ですが、そもそもTCPというのは「細切れでデータを送ってくる」ものですから、これを変えるのはナンセンスだと思います(^^;

DataArrivalでデータを受け取ったら、バッファに追加。そこでフッタデータが見つかればそこまでのバッファを処理データとして、バッファからその部分を消去し、処理データを処理する。
バイナリデータ送受信の場合、バイナリデータとヘッダ・フッタデータが被ることが考えられるので、ヘッダに「今から***Byteのデータを送る」ということを明記させる仕様にする。

こんな感じではないでしょうか。

投稿日時 - 2005-07-28 15:26:54

お礼

勉強になりました。
今までたまたま処理する文字数が少なかったので、大丈夫だったのですね(汗)

アドバイスどうもありがとうございます。
ただ、バッファの構造が分かりません(汗)

ヘッダーとフッタの間は、どうやって判別するのですか?
複数処理(BBSとChatなど)のデータが来たら、混じってしまう?のでは?

小包(?)ごとに、ヘッダーが必要になるのかな?なんて思ってしまいました。

初歩的なことを聞いてすみません。。。

↓こんなのありました。
http://www.kt.rim.or.jp/~ksk/wskfaq-ja/articles/effective-tcp.html

投稿日時 - 2005-07-28 17:27:27

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

# まだ見てるかどうか分かりませんが(^^;

>ただ、バッファの構造が分かりません(汗)

それは(VBプログラマであれば)意識する必要はないと思いますが・・・(^^;
それを作る(プロトコルを設計する)のは自分ですよ。

>ヘッダーとフッタの間は、どうやって判別するのですか?

データの流れとしては、必ず「ヘッダ~データ~フッタ」という感じになるはずです。(フッタは必ずしも必要ではありません。というか要らないか。)

また、「↓こんなのありました。」で紹介されているURLや先の回答で書きましたとおり、ヘッダにデータのサイズを埋め込んでおけば、ヘッダデータを受信してあとはそのサイズだけバッファを処理すればいいですね。

>複数処理(BBSとChatなど)のデータが来たら、混じってしまう?のでは?

例えば、Aさんが「こんにちわ」Bさんが「どういたしまして」というデータをサーバに送ったとします。
このとき、データを繋げると
「こんにちわどういたしまして」
「どういたしましてこんにちわ」
の、どちらかに必ずなります。

どちらが先に送ったか、という順番は、TCPでは保証されませんが、Send()で送った分のデータの塊分は、細切れになっていても必ずこの順で届きます。

ですので「混じらないようにプロトコルを設計する」というのが正しい解答です(^^;
# 「チャット プロトコル」あたりのキーワードで検索してみましょう

>小包(?)ごとに、ヘッダーが必要になるのかな?なんて思ってしまいました。

1回のSend()ごとにヘッダが必要になる、ということでしたらそのとおりです。

投稿日時 - 2005-07-31 22:08:05

お礼

昨日、アドバイスを頂いてから、今まで考えていましたが、バッファデータが「混じらないようにプロトコルを設計する」って難しいですね。実際にコーディングして試行錯誤してみます。


>このとき、データを繋げると
>「こんにちわどういたしまして」
>「どういたしましてこんにちわ」
>の、どちらかに必ずなります。

分かりやすい例をありがとうございます。


私の分かりにくい質問にもかかわらず、2回もアドバイスしていただいて、ありがとうございました。

投稿日時 - 2005-08-01 09:29:31

あなたにオススメの質問