![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?8acaa2e)
Winsock2.hを使って通信プログラムを作っています。
座標などのパラメータを短いスパンで送受信して処理をするものなのですが、
send()で送れるデータ型がchar*型ということなのでパラメータをwsprintf()を使って
SOCKET s;
int x=100;
int y=100;
int z=100;
char buf[16];
wsprintf(buf,"#%04d#%04d#%04d",x,y,z);
send(s,buf,strlen(buf),0);
のようにして送信して、受信されたデータはstrtok()で区切りながらそれぞれ格納しています。
SOCKAT s;
int x,y,z;
int nResult;
char buf[16];
char *tp;
nResult = recv(s,buf,sizeof(buf),0);
tp = strtok(buf,"#");
x=atoi(tp);
tp = strtok(buf,"#");
y=atoi(tp);
tp = strtok(buf,"#");
z=atoi(tp);
という感じなのですが、パラメータが増えていくにつれなんというか冗長というか、
もうちょっと賢いやり方があるような気がしていろいろ調べてはみたものの…
あまりデータの扱い方に関しての解説が見つからなかったので質問させていただきました。
ということで、他に複数の変数を纏めて送受信して処理する手法(できれば高速に)をご存知でしたらご教授お願いします。
No.2ベストアンサー
- 回答日時:
#1です。
すいません。なんか誤ってプログラム部分だけ送信してしまいました。
sendの引数はchar*ですが、別にバイナリーデータを送信しても問題ありません。
同じi386CPUのWindowsマシン間で通信する、という条件があるのでしたら、送信データを構造体にして、構造体のデータを送信するのが一番てっとりばやいと思います。
その具体例が#1のソースになります。
なお、ソースは動作は確認しておりません。
あしからずご了承ください。
回答ありがとうございます。
バイナリで送れたんですね。
パラメータが増えてきて複雑なトークン分けを行っていたのでおかげでかなり楽になりました。
No.3
- 回答日時:
#1の回答にあるように「バイナリデータのまま送受信」が効率的ですが、その場合は、longやintやshortの扱いに注意しましょう。
送信側と受信側で、intやshortのデータの「バイト並び順」が一致している保証は無いので「バイトの並び順を統一する」必要があります。
以下のページを参考に
http://msdn.microsoft.com/ja-jp/library/3thek09d …
送信側では「ホストのバイト順からネットワークのバイト順に変換」を、受信側では「ネットワークのバイト順からホストのバイト順に変換」を行う必要があります。
送信側の例(x,y,zは32ビットと想定)
senddata.x = htonl(x);
senddata.y = htonl(y);
senddata.z = htonl(z);
受信側の例(x,y,zは32ビットと想定)
x = ntohl(senddata.x);
y = ntohl(senddata.y);
z = ntohl(senddata.z);
回答ありがとうございます。
他の方法を調べていたとき、構造体を送る方法も見つけたのですがエンディアンの都合であまりお勧めできないというようなことが書いてあって見送っていたのですが、
ネットワークバイトオーダーの変換を利用すればよかったんですね。
No.1
- 回答日時:
typedef struct _TSendData {
int x;
int y;
int z;
} TSendData;
// 送信側
int SendData(SOCKET s, int x, int y, int z)
{
// 送信データの作成
TSendData senddata = {0};
senddata.x = x;
senddata.y = y;
senddata.z = z;
int done = 0;
int r;
char* sendptr = (char*)&senddata; // 送信する先頭アドレスを取得
// 送信データを全て送り終わるまでループする
while( done < sizeof(TSendData) ) {
// 未送信の部分を送信してみる
r = send(s, sendptr, sizeof(TSendData) - done, 0);
// 送信結果がエラーなら終了
if( r <= 0 ) return r;
// 未送信データアドレスと送信完了バイト数を更新
sendptr += r;
done += r;
}
return done;
}
// 受信側
// 返り値は読み込んだバイト数orエラーコード
// data に受信結果が挿入される
int RecvData(SOCKET s, TSendData* data)
{
// 受信データアドレスの設定
char* recvptr = (char*)data;
int done = 0;
// 受信データを1つぶん読み込むまでループする
while( done < sizeof(TSendData) ) {
// 未受信データアドレスに実際にデータを読み込む
int r = recv(s, recvptr, sizeof(TSendData)-done, 0);
// エラーだったら終了する
if( r <= 0 ) return r;
// 未受信データアドレスと受信完了バイト数を更新
recvptr += r;
done += r;
}
return done;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
- C言語・C++・C# #include <stdio.h>int main(void) { int buf[100] = 6 2022/11/01 22:45
- C言語・C++・C# C言語のバイナリファイルに関する質問 8 2022/06/24 07:20
- Visual Basic(VBA) Excel-VBAでのファイルの開き方 4 2023/02/14 11:01
- Visual Basic(VBA) 複数csvを横に追加していくマクロについて 2 2023/04/25 09:19
- Excel(エクセル) 2つのVBAを一緒にしたら機能しなくなりました(エクセル) 7 2022/06/02 12:41
- Visual Basic(VBA) オブジェクトが見つかりません 1 2023/06/24 19:43
- Visual Basic(VBA) findメソッドの変数について 6 2023/06/23 08:01
- Visual Basic(VBA) フォルダの場所を可変にしたいです(マクロ) 4 2023/05/11 10:00
- Excel(エクセル) エクセル VBA For Next 繰り返しの書き方を教えてください 6 2022/09/01 14:11
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
sizeof(char *)
-
干支のプログラム
-
コマンドラインに入力されてい...
-
テキストデータをそのままバイ...
-
int型からchar型への変換
-
構造体の各メンバにfor文からア...
-
c言語配列の結合についてです。...
-
C言語プログラミングについて(...
-
C言語のfor文です。 繰り返しの...
-
Visual Studio strcpyについて
-
VC++でコンパイルエラーが出ま...
-
charでの計算?
-
C言語のポインターで詰まっている
-
数字文字の出現回数を表示する...
-
【C言語】構造体内の領域解放(...
-
sprintf関数の作り方
-
c言語プログラミング実行時エラ...
-
double型の値をchar配列に変換...
-
文字列ポインタを結合
-
C++ Switch文について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
C言語のfor文です。 繰り返しの...
-
テキストデータをそのままバイ...
-
charでの計算?
-
文字列から空白を取り除きたい...
-
charからLPTSTRへの変換方法
-
atoi( ) の反対をやりたい
-
2曲同時再生するにはどうした...
-
C言語の入力した文字を反転させ...
-
配列をnビットシフトする
-
3桁区切(コンマ)記号をつけ...
-
int main()の・・・
-
型変換
-
CStringをwchar_tに変換したい
-
'const char *' 型は 'char *' ...
-
間接操作のレベルとは
-
double型の値をchar配列に変換...
-
c++ 文字列を入力して、一文字...
-
絶対パスからのファイル名の切...
-
switch文で文字を比較すること...
おすすめ情報