@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

SOCKET通信での受信データ処理について

1
投稿者投稿内容
jet_tetsu
会議室デビュー日: 2004/10/20
投稿数: 2
投稿日時: 2004-10-22 01:23
今、ソケット通信で受信したデータの処理について、悩んでいます。

Socketを使用してTCP/IP通信を行い、外部からの受信データを、先頭の4バイトの整数型データによって、以下の異なる2種類のクラスから生成されるオブジェクトに振り分けるというものです。
データはリトルディアンで送信されます。

public class A {
int code;
byte b1;
byte b2;
}

public class B {
int code;
float f1;
float f2;
}

今回、受信側(自身)がクライアント、送信側がサーバとなります。サーバのアプリはJAVAとは限りません。

Socketクラスからオブジェクトsocketを生成し、
標準入力ストリームInputSteamに、socketの入力ストリームを渡します。
InputStream reader = socket.getInputStream();

次に、バイト型の配列を作成し、そこに受信データを取得します。
byte [] data = new byte [256];
reader.read(data);

以上、ここまではわかるのですが、まず、

疑問点1:byte配列の先頭の4バイトをint型にキャストする方法がわかりません。

次に、先頭の4バイトをint型の変数codeにキャストしたら、
codeの値(1or2)によって、クラスAもしくはクラスBのオブジェクトを生成し、
受信データ全体を、生成したオブジェクトにキャストします。

if (code == 1) {
A a = new A;
<< a <-- (キャスト)-- data >>
system.out.println ("b1="+a.b1+",b2="+a.b2);
}
else if (code == 2) {
B b = new B;
<< b <-- (キャスト)-- data >>
system.out.println ("f1="+b.f1+",f2="+b.f2);
}

疑問点2:上記で<< >>で囲った、dataをaもしくはbへキャストする方法がわかりません。

以上、2点の疑問について、いろいろ調べてはみたのですが、結局解がみつかりませんでした。
お知恵をお貸しいただけますよう、よろしくお願いします。

ちいにぃ
大ベテラン
会議室デビュー日: 2002/05/28
投稿数: 244
投稿日時: 2004-10-22 01:56
動作は確かめていませんが、byte[]からByteBuffer経由、あるいは
InputStreamからDataInputStream、あるいは、
SocketChannelからByteBuffer経由で取得できると思います。

ByteBuffer#wrap(byte[] array) で ByteBufferを作って、
ByteBuffer#getInt() で読み出し。

Big/Little-Endian の対処は、
ByteBuffer#order(ByteOrder bo) で。

あるいは、byte[]を経由せずに、
Socket#getInputStream から DataInputStream を作って、
DataInputStream#readInt() とか。
(でも、Big/Little-Endianの切り替え方法は知らない)

また、Socket#getChannel -> ByteBuffer もできるかも知れませんが、
調べていません。APIdoc見てみてください。
jet_tetsu
会議室デビュー日: 2004/10/20
投稿数: 2
投稿日時: 2004-10-22 03:25
ということは、

Socket socket = new Socket (アドレス,ポート);

InputStream reader = socket.getInputStream();

byte [] data = new byte [256];
reader.read(data);

ByteBuffer byBuf = new ByteBuffer();
byBuf.wrap (data);

if (code == 1) {
A a = new A;
b1 = byBuf.get ();
b2 = byBuf.get ();
system.out.println ("b1="+a.b1+",b2="+a.b2);
}
else if (code == 2) {
B b = new B;
f1 = byBuf.getFloat ();
f2 = byBuf.getFloat ();
system.out.println ("f1="+b.f1+",f2="+b.f2);
}

ということですね。
また、確かに、Socketの代わりにSocketChannelを使う方法も、今回のケースには向いてそうですね。

早速のご回答、ありがとうございました。
非常に参考になりました。
1

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