- PR -

フィールドの値をバイトデータに変換してサーバとクライアントでやり取りする方法

1
投稿者投稿内容
ひらふ
会議室デビュー日: 2008/05/30
投稿数: 5
投稿日時: 2008-06-13 19:32
会議室のみなさん、よろしくお願いします。

現在、サーバがjava、クライアントがC#というプログラムを作成しています。
サーバとクライアントの通信はソケットで行います。
そして以前、javaとC#でオブジェクトを通信するにはどうすればいいか、
という質問をさせていただきました。
質問に答えてくださった方の意見を参考にして、
もう一度作成しているプログラムの通信に何が必要かについて考えてみました。

もう一度プログラムについて考えてみたところ、
オブジェクトそのものを送らなくても、
オブジェクトのフィールドの値をバイトデータで送ればいいのではないかと考えました。

今考えている方法は、次のようなものです。
サーバとクライアントの間でやり取りするメッセージ全体のバイト長を決めておき、
メッセージの先頭から何バイトまではメッセージのタイプ、
次のバイトから何バイトまではユーザのリスト、
次のバイトから何バイトまでは画像データという様にメッセージの構造を定義し、
各データフィールドのバイト長を決めておきます。
データを受け取った側はメッセージの構造が定義されており、
各データフィールドのバイト長も分かっているので、
受け取ったバイトデータから元のメッセージの構造を再現できます。

このような方法を考えています。
扱いたいフィールドは以下のものです。

int type; //送信データの識別子
int count; //回数
string[] name; //ユーザのリスト
byte[] bim; //byte[]型画像データ

これらのフィールドをtypeから順に送信側でバイトに変換し、
受信側で再び元のフィールドの値に復元したいと考えています。



質問したいのは二つです

・javaとC#それぞれでフィールドの値をバイト長を決めたバイトデータに変換し、
 もう一度フィールドの値に復元するには具体的にどうすればいいか

・ユーザリストのサイズは決まっていないのでバイトに変換する際、
 どのように扱うべきか(一人もいない時や多くの人がいる時もある)


オブジェクトを直接やり取りすることも考えていますが、
こちらの方法も試してみたいと考えています。

質問の直接の答えでなくても何かアドバイスいただければ幸いです。
よろしくお願いします。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-06-13 20:58
引用:

ひらふさんの書き込み (2008-06-13 19:32) より:
・javaとC#それぞれでフィールドの値をバイト長を決めたバイトデータに変換し、
 もう一度フィールドの値に復元するには具体的にどうすればいいか


javaとC#それぞれでフィールドの値をバイト長を決めたバイトデータに変換し、もう一度フィールドの値に復元します。
「具体的」というのが良く分かりませんが、まずは int 1つだけをやりとりしてみてはどうでしょうか。

引用:

ひらふさんの書き込み (2008-06-13 19:32) より:
・ユーザリストのサイズは決まっていないのでバイトに変換する際、
 どのように扱うべきか(一人もいない時や多くの人がいる時もある)


可変長の要素を持つ場合は、あらかじめエンドマークを決めておくか、要素を列挙する前に要素数を置くか、のいずれかをやります。
後者のほうがなにかとやりやすいと思います。
コード:
int type; //送信データの識別子 
int count; //回数 
int nameSize; //ユーザのリストの要素数
string[] name; //ユーザのリスト 
int bimSize; // bim の要素数
byte[] bim; //byte[]型画像データ


みたいな感じです。

引用:

ひらふさんの書き込み (2008-06-13 19:32) より:
オブジェクトを直接やり取りすることも考えていますが、
こちらの方法も試してみたいと考えています。


いまどきは、たいていのことは XML でやることが多いです。XML を使う SOAP などは確かに、覚えることが多いという意味でオーバーヘッドが大きいですが、大規模なシステムでは普通に使われるものなので、SOAP の周辺技術を使ってやるほうが私は良いと思います。
ただ、SOAP も XML も完全に枯れた(安定した)技術ではないので、おっしゃるようにオブジェクトを意識しないプレーンなやりかたも、それなりにメリットはあるとは思います。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-06-13 21:02
まずは、送信も受信もひとつの言語だけでやりとりすることを試されてはどうでしょうか。
たとえば Java だったら、Externalizable を使って、送信・受信をやってみます。ネットワークを介した通信でなくても、ファイルに書いてそれを読むのがデバッグもバイナリーエディターで解析できてやりやすいです。

オブジェクトを指向しないのならば、Externalizable すら使わなくても良いですが、雰囲気を掴むときは最初は使ったほうが逆に分かりやすいかもしれません。必須ではないですが。

[ メッセージ編集済み 編集者: unibon 編集日時 2008-06-13 21:04 ]
ひらふ
会議室デビュー日: 2008/05/30
投稿数: 5
投稿日時: 2008-06-14 09:13
unibonさん返信ありがとうございます。


「具体的」にというのは、フィールドの値をバイト変換をするのにどのようなプログラムを書けばいいのかということで、
intやstring等、場合に応じてそれぞれ変換の仕方に違いはあるのかどうかを質問したかったのです。
説明不足ですみませんでした。

可変長の要素を持つ場合に関しての説明は試してみようと思います。

言語の選択に関しては、そういう仕様でプログラムを作成しているので現在のところ変更できません。


良ければ、引き続きバイト変換のプログラムをどのように書くかについて質問したいと思います。
もし勉強すれば簡単に理解できる内容ならば、勉強するための資料の紹介をしていただければありがたいです。

よろしくお願いします。


unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-06-14 11:09
引用:

ひらふさんの書き込み (2008-06-14 09:13) より:
言語の選択に関しては、そういう仕様でプログラムを作成しているので現在のところ変更できません。


最終的な要求仕様としては、Java で書いて C# で読む、か、C# で書いて Java で読む、のいずれかだとは思います。しかし、練習としては、まずは Java で書いて Java で読む、や、C# で書いて C# で読む、から取り掛かったほうがよいのでは、ということを前回は述べました。

引用:

ひらふさんの書き込み (2008-06-14 09:13) より:
良ければ、引き続きバイト変換のプログラムをどのように書くかについて質問したいと思います。
もし勉強すれば簡単に理解できる内容ならば、勉強するための資料の紹介をしていただければありがたいです。


Insider.NET 会議室 > C#でのバイト列操作について
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?mode=viewtopic&topic=11404&forum=7
は、C# でやりとりしている例のようです。

ネットで少し検索してみましたが、これ(バイト列操作)だけをメインに解説したサイトはなかなかすぐには見つからないようですが、TCP や UDP 通信の解説のついでに書いてあるものはわりと見つけやすいような感じがしました。検索キーワードにソケット通信あたりの API のクラス名やメソッド名を付けてみるとよいかもしれません。
いっきゅう
大ベテラン
会議室デビュー日: 2004/04/04
投稿数: 153
お住まい・勤務地: 兵庫
投稿日時: 2008-06-14 11:17
引用:

質問したいのは二つです

・javaとC#それぞれでフィールドの値をバイト長を決めたバイトデータに変換し、
 もう一度フィールドの値に復元するには具体的にどうすればいいか

・ユーザリストのサイズは決まっていないのでバイトに変換する際、
 どのように扱うべきか(一人もいない時や多くの人がいる時もある)


オブジェクトを直接やり取りすることも考えていますが、
こちらの方法も試してみたいと考えています。

質問の直接の答えでなくても何かアドバイスいただければ幸いです。



Javaなら
java.io.DataInputStream
java.io.DataOutputStream

C#なら
BitConverter

あたりを使いますが、調べたらいくらでもヒントは出てくると思いますよ。
わたなべ
大ベテラン
会議室デビュー日: 2007/12/09
投稿数: 123
お住まい・勤務地: 札幌
投稿日時: 2008-06-14 14:12
バイナリで送る必要があるのですかね?
用途がどのようなものか解りませんけど、プレインテキスト(CSV形式とかKey=Value形式とか・・・)でやり取りすれば簡単なのでは?

どのようにバイナリに変換して、どのように戻すか・・・それは決めた方法に従うだけです。
ある程度ルールが決まっている形式の方が簡単です。
その方法が思いつかないならばバイナリで送るよりテキストで送った方が良いと思います。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2008-06-14 18:46
前に汎用のプロトコルであるSOAPでやれば?とアドバイスして却下されてましたよね?
バイナリといっても、単純に言語のAPIとして用意されている方式では、
大抵どんな言語でも他の言語とのやりとりは考慮されていないわけですよ。
だから、そのために汎用のプロトコルであるSOAPとかがあるわけです。

引用:

・javaとC#それぞれでフィールドの値をバイト長を決めたバイトデータに変換し、
 もう一度フィールドの値に復元するには具体的にどうすればいいか

・ユーザリストのサイズは決まっていないのでバイトに変換する際、
 どのように扱うべきか(一人もいない時や多くの人がいる時もある)


自分でプロトコルを決めればよいのです。
どういう順番でデータを書き込むか、読み出すか、単にそれだけです。
そして読み出した結果に基づいてオブジェクト化すれば終わりです。

可変長のデータの読み出しなら、要素がどれだけあるかをデータとして示せばよいでしょう。
例)データ個数、文字列長、文字列、文字列長、文字列、文字列長、文字列・・・・

何度も言って申し訳ないですが、
こういうことを考えなくてもいいように、汎用なフォーマットがあるわけです。
その汎用フォーマットに対応したライブラリも、それなりに揃っています。
なので、こういうことも考える必要がないですし、
新たにオブジェクトの通信の手続きを実装する必要もないのです。
1

スキルアップ/キャリアアップ(JOB@IT)