Winsockでの受信量取得

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
雲居

Winsockでの受信量取得

#1

投稿記事 by 雲居 » 16年前

夜遅くに申し訳ありません。

クライアントはDXライブラリ、サーバーはWinsock+コンソールにて通信プログラムを組んでいるのですが
実際に受信する前にきているパケットの量を得ることはできますでしょうか?
データタイプ毎に受信する量が異なるので、あらかじめ来ているデータ量を取得し、
recvにてそのデータ量分受信したいです。

// 受信
int DataLength;
DataLength = 来ているデータ量を得る
recv(sock, buff, DataLength, 0);

// データタイプ
enum DATA_TYPE
{
Type_A,
Type_B,
}

struct PacketHead
{
DATA_TYPE type;
char Data[256];
}

struct Type_A_Data
{
int a;
int b;
}

struct Type_B_Data
{
char msg[256];
}

それとも、データの頭2byteにデータタイプを入れておき、
受信 recv(socket, buff, RECV_MAX, 0) 、
その後頭2byteで判別したデータサイズを抜き取り処理、の方がよいのでしょうか?

個人的には上記の構造体を用いた方法を利用したいのですが・・・
極力通信に使うデータ量をへらしたいのです。

また、データタイプの判別に他になにか良い手があれば
お教えいただけるとありがたいです。

Mist

Re:Winsockでの受信量取得

#2

投稿記事 by Mist » 16年前

雲居さんが考えられている方法は無理です。
Winsockが現時点で何バイト受信しているかを知ることは出来ますが、それはチェックした時点での総合計でしかないのでどちらの構造体のデータであるかを判別することはできません。
例えばType_A_Dataを32個受信するとType_B_Dataと同じ長さになりますが、Winsockからはどちらも256バイト受信としか返らないので判別できないです。

> それとも、データの頭2byteにデータタイプを入れておき、
> 受信 recv(socket, buff, RECV_MAX, 0) 、
> その後頭2byteで判別したデータサイズを抜き取り処理、の方がよいのでしょうか?
このようなメッセージのヘッダにタイプなりメッセージ長なりをくっつけるのがスタンダードではないでしょうか。
1.ヘッダだけ受信
2.メッセージタイプを判別
3.データ部を受信

あと、通信データを構造体で記述する場合はアライメントに注意する必要があります。

雲居

Re:Winsockでの受信量取得

#3

投稿記事 by 雲居 » 16年前

ヘッダを先に受信し、というと

//-------------------------------------------------------------------

/* 受信側 */
int length=0;

recv(sock, head, 2, 0); // 先頭2byteを取得

while(true)
{
// 先頭2byteと比較
if( strcmp(head, "00")==0 ) // DATA_TYPE_00
{
// ヘッダを除くデータ本体の受信
resv(sock, buff, DATA_TYPEごとの長さ-length, 0);
if(strlen(buff) == DATA_TYPEごとの長さ)
{
  printf("head[%s], buff[%s]\n", head, buff);
break;
}
else
{
printf("受信しきれていないので再受信");
length = strlen(buff); // 現時点までのパケットサイズの取得
}
}
}

//-------------------------------------------------------------------

/* 送信側 */
// データのセット
strcpy(buff, "00"); // DATA_TYPE_00をセット
stacat(buff, "Hello."); // データ内容をセット

// 実際に送信
send(socket, buff, strlen(buff), 0);

//-------------------------------------------------------------------

ということで問題はなさそうですか?

また構造体での送受信、判別にはDXライブラリ本家の掲示板より
http://hpcgi2.nifty.com/natupaji/bbs/pa ... no=611&p=2
を参考にしていますが、これはDXライブラリの仕様上可能なだけなのでしょうか?

****備考****
DXライブラリは受信したものを一時記憶バッファに入れておき、
その長さをGetNetworkDataLengthで取得している、であってますでしょうか?

雲居

Re:Winsockでの受信量取得

#4

投稿記事 by 雲居 » 16年前

上記の掲示板の内容は、サイズ固定(256)での話でした^^;


追加で質問してもよろしいでしょうか?

構造体を送信するため、先に構造体のサイズを示すヘッダ(2byte)を送信、続いて本体の構造体の送信を行い、
サーバではまずヘッダ(2byte)を受信、判別し、続けて同ソケットから本体がきたらタイプ別サイズを受信して処理
という形をとることによって無事可変サイズの送受信に成功したのですが
この方法だと送信側、受信側共に1データに付き2の通信を行います。
これをどうにか1データにつき1通信にできないでしょうか?

バグ

Re:Winsockでの受信量取得

#5

投稿記事 by バグ » 16年前

普通に考えれば無理じゃないでしょうか?
あらかじめサイズを読み取っておかなければ、構造体部分を読み取る為の情報が無いんですから…
サイズを固定にすればヘッダが不要になりますが、可変だからヘッダが必要な訳で…

雲居

Re:Winsockでの受信量取得

#6

投稿記事 by 雲居 » 16年前

>>バグさん
返信ありがとうございます。
ややり無理ですか・・・
とりあえずパケと本体を別で送受信する方法でいこうかとおもいます。

ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る