- PR -

文字コードを指定したテキストと、バイナリの混在したデータをsocketで送信

投稿者投稿内容
らいん
会議室デビュー日: 2006/03/09
投稿数: 6
投稿日時: 2006-03-09 12:17
はじめまして。

現在、socketを利用して
Linuxサーバからホストへのデータ送信プログラムを作成しております。

ホストへ送信するデータは、

ヘッダー + 送信メッセージのlength + 送信メッセージ + フッター

という形式なのですが、
「送信メッセージのlength」のみバイナリで、その他テキストは、
ホストが読み取れるようにSHIFT-JISにして送らないといけません。

DataOutputStreamを用いると、
バイナリ部分はwrite()で正しく送信できるのですが、
テキスト部分はSHIFT-JISにしないといけないので
writeEUC()が使用できず、詰まってしまっております。

こちらのページに、解決方法らしきものがかかれていたのですが、
初心者のためにうまく利用することができませんでした。
http://java-house.jp/ml/archive/j-h-b/022439.html#body

どなたか、サンプルコード等を見せてくださった上で
どのようにすべきかをご指導くださいませんでしょうか。
大変申し訳ありませんが、ぜひともよろしくお願いいたします。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2006-03-09 13:34
プロトコルのレベルで細かいコーディングせずに、HTTPなど既存のものを使ってみるのはいかがでしょう?
サーバ側にJettyを使って、クライアント側は HttpURLConnection とか HttpClient とか。
らいん
会議室デビュー日: 2006/03/09
投稿数: 6
投稿日時: 2006-03-09 15:04
インギ様

ご返信ありがとうございます。
私はLinux側のクライアントプログラムしか触れないようになっております。
サーバーであるHOST側は、
クライアントとやり取りするためだけに開けられているポートがあり、
そこに対してクライアントからメッセージを投げればサーバーが受け取る、
といったのみのプログラムになっているようなのです。

ですので、ご教授いただいた方法が多分、使用できないですよね・・・
無知で申し訳ありません。
私の認識は正しいでしょうか?



[ メッセージ編集済み 編集者: らいん 編集日時 2006-03-11 19:46 ]
K
大ベテラン
会議室デビュー日: 2004/04/07
投稿数: 174
投稿日時: 2006-03-09 15:11
ようするに既にプロトコル仕様は決まっていて変えられないということですね。
受信側ではなく送信側ということなので、あらかじめ文字列もメモリ上でbyte配列にしておいてまとめて送信すればよいだけではないでしょうか?


らいん
会議室デビュー日: 2006/03/09
投稿数: 6
投稿日時: 2006-03-09 15:30
moge様

ご返信ありがとうございます。

>既にプロトコル仕様は決まっていて変えられない
そのとおりでございます。

初歩的な質問で申し訳ないのですが、文字列をbyte配列にした場合、
SHIFT-JISで送信、というように文字コードを指定できるのでしょうか?


お恥ずかしい限りなのですが、私が作成したプログラムを載せ忘れておりましたので、
ここで載せさせていただきます。
送信をしている部分と、文字コード変換、lengthをbyteに格納しているメソッドを
抜粋いたします。

【送信部分】
socket = new Socket(
getClientProprties().getProperty("host.name"),
Integer.parseInt(getClientProprties().getProperty("host.port")));

// output stream
out = new DataOutputStream(socket.getOutputStream());

//16進で示されているメッセージのlengthをプロパティより取得
String length = getClientProprties().getProperty("length.param");

//ヘッダーをプロパティより取得し、SHIFT-JISにして送信
out.writeChars(toSJIS(getClientProprties().getProperty("start.param")));

//16進の数値をbyteに格納し、送信
out.write(toByte(length));

//引数に該当するメッセージをプロパティから取得し、SHIFT-JISにして送信
out.writeChars(toSJIS(getMessageFileName().getProperty(args[0])));

//フッターをプロパティより取得し、SHIFT-JISにして送信
out.writeChars(toSJIS(getClientProprties().getProperty("end.param")));
out.flush();


【上記で使用しているメソッド】

//文字列をSHIFT-JISにしているメソッド
private static String toSJIS(String value) throws UnsupportedEncodingException{
return new String(value.getBytes(), "SJIS");
}

//16進の数値をbyteに格納にしているメソッド
private static byte[] toByte(String value){
ByteArrayOutputStream barray = new ByteArrayOutputStream();
for(int i = 2; i <= value.length(); i += 2){
barray.write(Integer.parseInt((value).substring(i-2, i), 16));
}
return barray.toByteArray();
}
K
大ベテラン
会議室デビュー日: 2004/04/07
投稿数: 174
投稿日時: 2006-03-09 15:50
えーと、細かいところはいろいろ問題ありそうですが、とりあえず、お望みのSJISの
文字列が生成できていることを前提とすると、
単に、
byte[] data = "SJISになっている文字列オブジェクト".getBytes("SJIS");
out.write(data,0,data.length);
でいけませんかね?

らいん
会議室デビュー日: 2006/03/09
投稿数: 6
投稿日時: 2006-03-09 15:58
moge様

ご返答ありがとうございます!
早速やってみます!
何から何まで本当に申し訳ありません。。

>細かいところはいろいろ問題ありそうですが
お恥ずかしい限りです・・・

サーバールームに移動いたしますため、すぐに結果を書き込むことはできませんが、
必ず結果をお伝えさせていただきます。
らいん
会議室デビュー日: 2006/03/09
投稿数: 6
投稿日時: 2006-03-10 18:19
moge様、インギ様

遅くなりました。
(案の定他の部分でうまくいかなくて)時間がかかってしまいましたが、
無事にホストにデータを送信できました!!!
本当に嬉しいです。
ありがとうございました!!

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