C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: C#で通信データを構造体にcastしたいのですが。


(過去ログ 48 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■26468 / inTopicNo.1)  C#で通信データを構造体にcastしたいのですが。
  
□投稿者/ ぼつ (1回)-(2008/10/09(Thu) 21:45:53)

分類:[C#] 

はじめまして。
C#初心者です。

開発環境:VS2005 C#

サーバ・クライアント間でデータの送受信(TCP/IP)を行う際に、送信データを構造体にセットして、
受信時にデータを取り出しやすく作りたいと思っています。(C言語ではそのような記述で動作させた事があります。)
例えば、下記のようなデータを構造体にしてやりとりしたいのですが、C#では構造体をcastできないのでしょうか?
       char A[5];
       char B[2];
int C;
long D;

もしくはもっと便利な書き方があるのでしょうか?
ちなみに通信相手は、WindowsでないOSでC言語で記述しています。

初めての質問で上手く質問できていませんが、よろしくお願いします。





引用返信 編集キー/
■26471 / inTopicNo.2)  Re[1]: C#で通信データを構造体にcastしたいのですが。
□投稿者/ やじゅ (685回)-(2008/10/10(Fri) 01:02:49)
やじゅ さんの Web サイト
No26468 (ぼつ さん) に返信
> サーバ・クライアント間でデータの送受信(TCP/IP)を行う際に、送信データを構造体にセットして、
> 受信時にデータを取り出しやすく作りたいと思っています。(C言語ではそのような記述で動作させた事があります。)
> もしくはもっと便利な書き方があるのでしょうか?
> ちなみに通信相手は、WindowsでないOSでC言語で記述しています。
>

XML形式で記述して、通信相手に受け渡すとか

引用返信 編集キー/
■26473 / inTopicNo.3)  Re[1]: C#で通信データを構造体にcastしたいのですが。
□投稿者/ Jitta on the way (191回)-(2008/10/10(Fri) 07:14:12)
No26468 (ぼつ さん) に返信
> はじめまして。
> C#初心者です。
>
> 開発環境:VS2005 C#
>
> サーバ・クライアント間でデータの送受信(TCP/IP)を行う際に、送信データを構造体にセットして、
> 受信時にデータを取り出しやすく作りたいと思っています。(C言語ではそのような記述で動作させた事があります。)
> 例えば、下記のようなデータを構造体にしてやりとりしたいのですが、C#では構造体をcastできないのでしょうか?
>        char A[5];
>        char B[2];
> int C;
> long D;
>
> もしくはもっと便利な書き方があるのでしょうか?
> ちなみに通信相手は、WindowsでないOSでC言語で記述しています。
>

構造体のコンストラクターで、バイトを取り出して代入すると言う方法になります。


アライメントと、エンディアンに要注意。その構造体、2+5+4+4 バイトじゃないですよ。
引用返信 編集キー/
■26474 / inTopicNo.4)  Re[2]: C#で通信データを構造体にcastしたいのですが。
□投稿者/ Jitta on the way (192回)-(2008/10/10(Fri) 07:21:18)
No26473 (Jitta on the way さん) に返信

> アライメントと、エンディアンに要注意。

訂正
バイト オーダー

引用返信 編集キー/
■26486 / inTopicNo.5)  Re[1]: C#で通信データを構造体にcastしたいのですが。
□投稿者/ 倉田 有大 (299回)-(2008/10/10(Fri) 18:21:54)
> ちなみに通信相手は、WindowsでないOSでC言語で記述しています。

もう書かれてますが、マシン変わるとバイトオーダーがかわるので、バイナリーそのまま送ってキャストは無理じゃないかと。
やったことないけど、シリアライズ、デシリアライズがいいのかな?

引用返信 編集キー/
■26487 / inTopicNo.6)  Re[2]: C#で通信データを構造体にcastしたいのですが。
□投稿者/ ぽぴ王子 (403回)-(2008/10/10(Fri) 18:50:59)
ぽぴ王子 さんの Web サイト
No26486 (倉田 有大 さん) に返信
>>ちなみに通信相手は、WindowsでないOSでC言語で記述しています。
>
> もう書かれてますが、マシン変わるとバイトオーダーがかわるので、バイナリーそのまま送ってキャストは無理じゃないかと。
> やったことないけど、シリアライズ、デシリアライズがいいのかな?

バイトオーダーは変わらないような気がするです。アライメントのことかな。
(CPUが変わったらバイトオーダーも変わる可能性はあるけれど)

結局のところ、そのままではダメというのは皆さんの共通認識なので、一項目ずつバラして転送するとか
テキストだったりXMLファイルだったり、影響をあまり受けない形式に変換して転送するということに
なるんじゃないかと思います。どうやるかは実装する人次第ですね。
シリアライズ&デシリアライズってのも広い意味でこれに含まれると思います。
引用返信 編集キー/
■26489 / inTopicNo.7)  Re[3]: C#で通信データを構造体にcastしたいのですが。
□投稿者/ ぼつ (2回)-(2008/10/10(Fri) 22:31:47)
みなさん返信ありがとうございます。

現在は、各変数間に区切り文字を入れて送信し、受信側で区切り文字を検出しポインタ移動させて各データの取り出しを行っています。
これが面倒というかメンテナンスしにくい書き方だったので、キャストしたいと思っていました。
みなさんのご意見からキャストはなかなか難しい事が分かりました。

XMLというのはまだ使った事がないので、少し勉強してみたいと思います。

Jitta on the way さんのおっしゃる「構造体のコンストラクターで、バイトを取り出して代入する方法」というのが勉強不足のため、あまりピンとこないのですが、classを作成するのでしょうか?
引用返信 編集キー/
■26492 / inTopicNo.8)  Re[4]: C#で通信データを構造体にcastしたいのですが。
□投稿者/ yamyam (1回)-(2008/10/11(Sat) 01:16:45)
No26489
> Jitta on the way さんのおっしゃる「構造体のコンストラクターで、バイトを取り出して代入する方法」というのが勉強不足のため、あまりピンとこないのですが、classを作成するのでしょうか?

これは、

No26489
> 現在は、各変数間に区切り文字を入れて送信し、受信側で区切り文字を検出しポインタ移動させて各データの取り出しを行っています。

この処理をするためのメソッド(コンストラクタでも何でも良いけど)を「構造体が持っていると、関連性が理解し易い」という感じですかね?
既にその処理は実装されている様ですので、その扱い方(表現?)の違いかと。
.Netだと構造体とクラスでコンストラクタの仕様に違いがあった気がするけど何だっけ?

参考までにこのような情報も。
ぬるり。
From Structure To Bytes:構造体へのポインタからByteの一次元配列へのキャスト方法
http://hongliang.seesaa.net/article/10208235.html

バイナリデータ中の何バイト目がヘッダ、データサイズ、チェックサム等ですよ、という仕様を決めて、
バイト配列をゴニョゴニョするのは...メンドクサイデスヨネ...
作った事はあるんですけどね(仕様は別)。仕事で。VB2005で。マルチスレッドで。TCPで。winsockで。
通信コンポーネントを使いたかったなぁ。



引用返信 編集キー/
■26497 / inTopicNo.9)  Re[4]: C#で通信データを構造体にcastしたいのですが。
□投稿者/ Jitta (522回)-(2008/10/11(Sat) 20:50:24)
Jitta さんの Web サイト
No26489 (ぼつ さん) に返信
> みなさん返信ありがとうございます。
>
> 現在は、各変数間に区切り文字を入れて送信し、受信側で区切り文字を検出しポインタ移動させて各データの取り出しを行っています。
> これが面倒というかメンテナンスしにくい書き方だったので、キャストしたいと思っていました。
> みなさんのご意見からキャストはなかなか難しい事が分かりました。
>
> XMLというのはまだ使った事がないので、少し勉強してみたいと思います。
>
> Jitta on the way さんのおっしゃる「構造体のコンストラクターで、バイトを取り出して代入する方法」というのが勉強不足のため、あまりピンとこないのですが、classを作成するのでしょうか?

 現在の構造体が、このようになっていると書かれています。
struct a {
  char A[5];
  char B[2];
  int C;
  long D;
};

 この構造体は、パッと見は 5+2+4+4 (long = int で 32bit とした場合)で15バイトのように見えます。
しかし、実際には16バイトあります。それは、メモリの使用領域が4バイトごとに整えられ、5+2 の後に整列用の1バイトが追加されるからです。(いくつかのコンパイラで、整えるのを何バイトにするか、選べます)
つまり、
struct a {
  char A[5];
  char B[2];
  char dummy; // ここにはアクセスできない
  int C;
  long D;
};
となっています。

 そのほかに、インテルおよびその互換 CPU は、複数バイトの場合に小さい桁が前に来ます。最近は UNIX も x86 互換で動くので同じなのかもしれませんが、通信相手によっては小さい桁が後ろにある場合があります。これがバイト オーダー。

 他の OS と通信をする場合、この二つがどうなっているか、きちんと押さえておく必要があります。

 今、「各変数間に区切り文字を入れて送信」と書かれていますが、おそらく、アライメントについて詳しくない人が、「送った桁と受け取った桁があわない」ことから、「区切り文字を入れて、ここまで、というのを示そう」としてしまったのではないかと思います。


 ですから、バイト オーダーが同じであることを確認し、アライメントの調整を行えば、キャストすることができます。
しかし、C# ではポインタをそのままでは扱えません。unsafe キーワードについて、調べてみてください。


 あ、5バイト2バイトであれば大丈夫だと思いますが、そこに「日本語の文字」は入るのでしょうか?入るのであれば、文字コードも調べておかなければなりません。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -