• ベストアンサー

文字化けします。

お世話になります。 ソケットでサーバとクライアントを接続しています。 コーディングの概略は次の通りです。 【クライアント】 PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"EUC_JP")); out.println("かきくけこ"); System.out.println(in.readLine()); 【サーバ】 PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"Shift_JIS")); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println(inputLine); out.println(inputLine); //←これはクライアントでも文字化けしない。 String s1 = "あいうえお"; String u1 = new String(s1.getBytes("xxxxx"), "yyyyy"); out.println(u1); //←文字化けする。 } お伺いしたいのは文字コード変換についてです。 サーバ:RedhatLinux クライアント:Windowsでして、 サーバ側コーディングの String s1 = "あいうえお"; としている文字列を クライアント側の // 読み込んだデータを表示 System.out.println(in.readLine()); で表示したいのですが、文字が化けて(????←このようになります)困っています。 文字コード変換しなければいけないと思うのですが、 getBytesを使うのでしょうか? もしgetBytesを使うならどのように書けばいいのかがわかりません。 分かりにくい説明で申し訳ありませんが、 ご教授ください。宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • kei5989
  • ベストアンサー率40% (11/27)
回答No.6

> Windows上でコーディングした、 > String str = "あああ"; > System.out.println(str); > をLinux上にFtpでアップして > 実行すると当然文字化けしますが、 > どのようにコード変換すればよいのでしょうか? えーっと、「Windows上でコーディング・コンパイルしたものをLinux上で実行すると文字化けする」ということですよね? 多分Windows上ではShift_JISで保存されてますよね。 で、LinuxではEUC_JPであると・・・ おそらく、ソース中でコード変換をするのではなく、ソースをEUC_JPで保存しなくてはならないのだと思います。 (前に一度ハマりました) そのときはEclipseを使って開発していたので、文字コードをEUC_JPと指定したらうまくいきました。 確か、Javaソースは実行環境と同じ文字コードで保存しなくてはいけないと記憶しています。 また、EUC_JPで保存したソースをWindows上で手動でコンパイルする場合、 javac -encoding EUC_JP xxx.java と文字コードを指定しなくてはならないようです。 (Eclipseはそこまでやってくれるようです) また外していたら申し訳ありません。

mikimiki777
質問者

お礼

ありがとうございました。 文字コード指定とかで対応できそうです。 丁寧なご指導ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (6)

  • deadlock
  • ベストアンサー率67% (59/87)
回答No.7

私の回答も誤解がありそうな部分があったので補足です。 >(1)#1の >>String str = "あああ"; >>System.out.println(str); >これは文字化けしないはずです。 ソースを文字コード変換なしでアップロードして、サーバ上でコンパイルしているのであれば、kei5989さんの仰る通り文字コードを指定する必要があります。 コーディング-実行環境間で文字コードが一致する必要はありませんが、コーディング-コンパイルでは一致させる必要があります。 コンパイル済みのクラスファイル(やjar, warなど)をアップロードしているのであれば、文字化けは起こりません。

mikimiki777
質問者

お礼

文字コードについていまいち理解していませんでしたがたいへん勉強になりました。ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • deadlock
  • ベストアンサー率67% (59/87)
回答No.5

はじめまして。まずは本題から。#1のk5989さんの回答にある、 new String(s1.getBytes("xxxxx"), "yyyyy") は削除してみましたか?多分これが原因です。 たとえば、UnicodeをShift_JISとして変換したバイト列を、EUCのバイト列のつもりで読み込めば、当然文字化けします。 Writerに書き込まれる前に、u1の時点で文字化けしているはずです。 s1を直接送信してみてください。 いくつか見当たるものを… (1)#1の >String str = "あああ"; >System.out.println(str); これは文字化けしないはずです。文字リテラルは、コンパイルする時点でUnicode変換されます。おそらく標準出力を見ているツール(Telnet端末?)の文字コード設定が間違っているのでしょう。 (2)サーバサイドの環境設定。 サーバでJavaのプロセスを動かしている環境設定では、文字コードはEUCですか?ログインシェルや、プロセスの起動シェルで文字コードが変更されている可能性がありますので、文字化けがおきたときはこの辺も確認してみてください。 (3)コード変換の場所をサーバ/クライアントどちらかに統一してください。 両方で変換をかけず、サーバのみ・クライアントのみで変換を書けるようにしたほうが分かりやすいでしょう。修正/コンパイルなどが楽な方で試してみてはどうでしょう。 また、両方で変換をかけるのであれば、通信に使うWriter/Reader生成時にはすべて同じエンコードを指定すると(2)であげたような環境設定に影響されずにすみます。

全文を見る
すると、全ての回答が全文表示されます。
noname#49664
noname#49664
回答No.4

>コンパイルして、実行しましたが >例外が出てしまいました。 あ、ひょっとしてコンパイルのときにエラーになりましたか? すいません。encodeは例外を発生させるので、この処理はtry内で実行する必要があります。書き忘れてました。

mikimiki777
質問者

補足

あ、すみません。 キャラクタセット名が悪かったみたいでした。 キャラクタセット名をAPIに記載しているものを一通りためしたのですが、うまくいきませんでした。 何か使い方が間違っているのでしょうか?

全文を見る
すると、全ての回答が全文表示されます。
noname#49664
noname#49664
回答No.3

とりあえず原因究明は脇に置いて、テキストを指定のキャラクタセットを使った形にエンコーディングする基本についてだけ。こんな感じでできると思います。 // import java.nio.*; // import java.nio.charset.*; が必要。 Charset iso = Charset.forName(キャラクタセット名); CharsetEncoder encoder = iso.newEncoder(); CharBuffer cbuf = CharBuffer.wrap(変換前テキスト.toCharArray()); ByteBuffer bbuf = encoder.encode(cbuf); String 変換済みテキスト = new String(bbuf.array()); データが破損しているとかでなく、本当にキャラクタセットが異なるために文字化けが起こっているのであれば、これでいろいろと変換して文字化けが解消するか試してみてはいかがでしょうか。

mikimiki777
質問者

補足

レスありがとうございます。 Windows上で String s1 = "あああ"; Charset iso = Charset.forName("EUC_JP"); CharsetEncoder encoder = iso.newEncoder(); CharBuffer cbuf = CharBuffer.wrap(s1.toCharArray()); ByteBuffer bbuf = encoder.encode(cbuf); String s2 = new String(bbuf.array()); System.out.println(s2); とコーディングして、 これをLinux上にアップロードして、 コンパイルして、実行しましたが 例外が出てしまいました。 使用方法が間違っているのでしょうか?

全文を見る
すると、全ての回答が全文表示されます。
  • kei5989
  • ベストアンサー率40% (11/27)
回答No.2

すみません、さっきの回答、間違ってますね。 よく見たら、サーバ/クライアントともにBufferedReader(受信側)ですね。 後半は読み捨ててください(汗)。 となると、原因がよくわからなくなってきますね・・・ inputLineもu1もStringなのに、u1だけ文字化けするなんて・・・ ちなみに、System.out.println(inputLine);では文字化けせずに表示されてますか? また、String u1 = new String(s1.getBytes("xxxxx"), "yyyyy");の変わりにSystem.out.println(s1);とするとどのように表示されますか?

全文を見る
すると、全ての回答が全文表示されます。
  • kei5989
  • ベストアンサー率40% (11/27)
回答No.1

こんばんは、mikimiki777さん。 ぱっと見ただけなので、外していたらゴメンナサイ・・・ まず、Java上のStringはすべてUnicodeでエンコードされていることは理解しておられますか? それを踏まえて見てみると、 >String s1 = "あいうえお"; >String u1 = new String(s1.getBytes("xxxxx"), "yyyyy"); s1はUnicodeです。 u1もUnicodeなのですが、「new String(s1.getBytes("xxxxx"), "yyyyy")」は何をしておられるのでしょうか? s1がすでにUnicodeである以上、ここでのコード変換は意味がないように思います。 String#getBytes(enc)メソッドはStringオブジェクトを文字コードをencとしてbyteの配列に変換するものです。 String(b, enc)コンストラクタはbyteの配列bを文字コードencとして解釈し、新たにStringオブジェクトを作るものです。 あくまで、Stringオブジェクトの中身はUnicodeであることを理解してください。 で、おそらく根本の原因はそこではないのですよね・・・ 私はソケットの経験はない上にソースも完全なものとは思えないので、憶測でしか言えませんが、クライアントとサーバで文字コードの指定(EUC_JPとShift_JIS)が異なっているのはよいのでしょうか? 私の理解では、 サーバでUnicodeからEUC_JPに変換して送信  ↓ クライアントでEUC_JPとして受信、Unicodeに変換してStringオブジェクトへ だと思うのですが・・・ ちょっとこれは本当に自信がありません。 外していたら申し訳ありません。

mikimiki777
質問者

補足

基本的なことを再度お伺いします。 Windows上でコーディングした、 String str = "あああ"; System.out.println(str); をLinux上にFtpでアップして 実行すると当然文字化けしますが、 どのようにコード変換すればよいのでしょうか? 基本的なことですみません。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • HttpのResponseが文字化け

    以下のプログラムの結果が文字化けします。 正しい文字コード(EUC-JP)にしているのですが 文字化けしてしまいます。 解消方法を教えて下さい。 ----- import java.net.*; import java.io.*; public class HelloWorldSocketClient { public static void main(String[] args) throws Throwable{ Socket socket = new Socket("www.sumishinam.co.jp", 80); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out.println("GET / HTTP1.0\n"); String buff; while((buff=in.readLine())!=null){ System.out.println(new String(buff.getBytes(),"EUC-JP")); } out.close(); in.close(); socket.close(); } }

  • サーブレットで文字化け

    サーバ Fedora Core 6 / tomcat5.5 クライアントもFedoraなら文字化けしません。 ウィンドウズxpから接続すると文字化けします。 アプレットのプログラムで送信する関数のみ抜粋した。引数sが送信する文字列でこれが文字化けします。送信した変数sをJLabelで表示するとウィンドウズでも文字化けしてなかった。そしてサーバー側のログは文字化けしていたのですが原因がわかりません。どうしたらいいですか? //■アプレット側 文字列送信用関数 public void send(String s) { try { sock = new Socket(サーバのIPアドレス,9999); //■サーバーに接続 fin = sock.getInputStream(); fout = sock.getOutputStream(); ffin = new InputStreamReader(fin); in = new BufferedReader(ffin); out = new PrintWriter(fout,true); out.println("POST / HTTP/1.1"); out.println("Accept: */* "); out.println("Accept-Language: ja"); out.println("Accept-Encoding: gzip,deflate"); out.println("User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"); out.println("Host: "+getParameter("ipAddress")); out.println("Content-Type: application/x-www-form-urlencoded; charset=UTF-8"); out.println("Content-Length: "+(s.getBytes("UTF-8").length)); out.println("Connection: Keep-Alive"); out.println(""); out.println(s); } catch(IOException e) { } } サーバー側 変数sの表示 public void service(HttpServletRequest req, HttpServletResponse res)throws ServletException,IOException { //■通信関係 PrintWriter out; BufferedReader in; //■入力した文字列 String st,str; try { //■通信開始 in = new BufferedReader(new InputStreamReader(req.getInputStream())); out = new PrintWriter(res.getOutputStream(),true); //■文字列読み込み st = in.readLine(); str = new String(st.getBytes("UTF-8")); System.out.println("受信した文字列"+str);

  • この各行のプログラムの意味を教えてください!

    各行のプログラムがなにをしてるかちょっとわからないので誰か教えてください><お願いします! PrintWriter out=new PrintWriter(socket.getOutStream(),true); out.println("hello,World!"); BufferedReader in=new BufferedReader( new InputStreamReader(socket.getInputStream()); String result=in.readLine();

    • ベストアンサー
    • Java
  • サーブレットについて

    public class Server extends HttpServlet { PrintWriter out; BufferedReader in; String s; public void doGet(HttpServletRequest req, HttpServletResponse res)throws ServletException,IOException { in = new BufferedReader(new InputStreamReader(req.getInputStream())); out = new PrintWriter(res.getOutputStream(),true); //文字列受信 s = in.readLine(); //送信 out.println(s); } } tomcatはマルチスレッドだと聞いたわけですが、このプログラムで、例えば、トムがアクセスしてきて、 s=in.readLine(); が実行されている間に2番目に接続してきたネコが out=new PrintWriter(); を実行してしまって out.println(s);で後から接続してきたネコに送信されるとゆうこともあるわけでしょうか?

    • ベストアンサー
    • Java
  • StringTokenizerについて

    ファイルの読み込みをStringTokenizerを使ってやりたいのですが、 使い方がいまいち理解できません。今自分で作っているプログラムでは効率が悪いです。 プログラムの一部を載せるのでアドバイスお願いします。 <プログラム> InputStreamReader fisr = new InputStreamReader(client. getInputStream()); BufferedReader fin = new BufferedReader(fisr); String name = fin.readLine(); System.out.println(name); while(n!=10){ FileInputStream objFis = new FileInputStream("eitango"+rand[n]+".txt"); InputStreamReader objlsr = new InputStreamReader(objFis,"Shift_jis"); BufferedReader objBr = new BufferedReader(objlsr); PrintWriter out = new PrintWriter(client.getOutputStream(),true); //1行ずつファイルを読み込む if (n==0){ out.println("Hello,clientNo:" + number +"\n"); } for(a=0;a!=6;a++){ if(a==5){ String ans = objBr.readLine(); ans2 = ans.length(); System.out.println("ans2 = "+ans2); } if(a!=5){ out.println(objBr.readLine()); } }

    • ベストアンサー
    • Java
  • echoサーバについて

    javaを勉強しています。 echoサーバをつかったサンプルがあり、vinelinux上でコンパイリし実行したのですが、ioexceptionの例外が出ているようです。 echoサーバは動いていないのでしょうか?? echoサーバが動いているかどうか確認する方法はないですか? このようなプログラムです。 import java.io.*; import java.net.*; public class EchoClient{ public static void main(String args[])throws IOException{ Socket echoS = null; BufferedReader in = null; PrintStream out = null; try{ echoS = new Socket("1300",7); in = new BufferedReader(new InputStreamReader(echoS.getInputStream())); out = new PrintStream(echoS.getOutputStream()); }catch(UnknownHostException e){ System.out.println("ホストに接続できません"); System.exit(1); }catch(IOException e){ System.out.println("ioコネクションを得られません"); System.exit(1); } BufferedReader stdln = new BufferedReader(new InputStreamReader(System.in)); String typedString; while((typedString = stdln.readLine()) != null){ out.println(typedString); System.out.println("サーバーからのエコー" + in.readLine()); } in.close(); out.close(); stdln.close(); echoS.close(); } }

    • ベストアンサー
    • Java
  • ソケットにおけるメッセージの送受信について

    いつもお世話になっています。 ソケットに関して質問します。 下記の手順でソケットを使用したいと考えています。 クラスAとクラスBが存在する。 1)クラスA:ソケット通信でメッセージ送信 2)クラスB:ソケット通信によるメッセージを取得 3)クラスB:ソケット通信で返信する 4)クラスA:ソケットによるメッセージを再取得する このとき、クラスAがクラスBによるメッセージ再信が、30秒以内にこなければ、ソケットを閉じる それにあたってソースを1クラスで実行できるよう書き変えたいのですが、どうも上手くいきません。 実行したいメソッド手順が ソケットを開く openSocket ソケットにメッセージ送信 sendMsg ・・・1と3はこのメソッドを使用 メッセージ取得 getMsg ・・・2と4はこのメソッドを使用 ソケットを閉じる closeSocket の順です。 自分で一度考えてみたソースは以下です。 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; public class Messaneger{ private Socket socket; private BufferedReader in; // ソケットを開く public void openSocket() { ServerSocket serverSocket; try { serverSocket = new ServerSocket(5555); System.out.println("クライアントからの接続をポート5555で待ちます"); // クライアントからの接続を待ちます Socket socket = serverSocket.accept(); System.out.println(socket.getInetAddress() + "から接続を受付ました"); // 出力ストリームを取得 PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // 入力ストリームを取得 in = new BufferedReader( new InputStreamReader( socket.getInputStream())); } catch (IOException e) {} } //ソケットを閉じる public void closeSocket() { try { socket.close(); } catch (IOException e) {} } /** * ソケット通信でメッセージを送信 * @param 送信するメッセージ */ public void setMsg(String sendMsg) { try { socket = new Socket("localhost", 5555); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // 入力ストリームを取得 in = new BufferedReader( new InputStreamReader( socket.getInputStream())); //サーバーにメッセージ送信 out.println( sendMsg ); //送信メッセージdata System.out.println(sendMsg); } catch (IOException e) {} } /** * ソケット通信でメッセージを取得 * @return msg サーバーに渡されたメッセージ */ public String getMsg() { String getMsg = ""; BufferedReader in; try { in = new BufferedReader( new InputStreamReader( socket.getInputStream())); System.out.println(in.readLine()); } catch (IOException e) {} return getMsg; } } 参考URL:http://www.hellohiro.com/socket.htm 宜しくお願いします。

  • Socket通信でのデータの受け渡し

    サーバーが受けたデータを、クライアントに返す プログラムですが、 サーバーは、クライアントからのデータを、 while(true){ BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream())); str=br.readLine(); if(str!=null){ PrintWriter pr=new PrintWriter(s.getOutputStream()); pr.println(str); pr.flush(); }}で、返すようにしています。 クライアントも大体同じです(PrintWriterは、 Buttonを押した時に、取得しています)。 考え方としては、inputstreamは、無限ループで、 取得し、outputstreamは、必要におうじて、取得し データを送っています。 しかし、これだと、一度データを送ると、次から データの受け渡しが出来なくなります。 socketか、inputstreamかoutputstreamのどれかが、 閉じるか、使えなくなるのだと思いますが、 いつもここで、悩んでいます。 (また、無限ループで、BufferedReaderオブジェクト をつくり続けるというのも、ちょっと不安)。 どこに問題があるのか、分かる人教えてください。 お願いします。

    • ベストアンサー
    • Java
  • Socketの使用方法について

    Socketの使用方法について サーバ側クラスA クライアント側クラスB とあり、Aは常駐しておりBから接続が合った場合に処理を行い、 処理後には待機状態に再び戻ります。 上記の場合に Aのクラスは以下のように作成しましたが、★の部分でCloseではなく、このままこのソケットを使用して待機したいです。 (ほぼ同時刻に複数のアクセスがあるため、資源の事を考えて使いまわしたいです。) どのような手段があるのかご指導お願い致します。 又、そもそもソケットに関しての理解が足りないとも思いますので、参考サイトを教えていただけると幸いです。 クラスA ServerSocket svsock = new ServerSocket(port); while (true) { Socket socket = svsock.accept(); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedWriter out = new BufferedWriter(new PrintWriter(socket.getOutputStream(), true)); // 処理結果を受信 String line; if ((line = in.readLine()) != null) { System.out.println("受け取ったメッセージ : " + line); out.write("サーバで表示。"); out.newLine(); out.flush(); } socket.close(); // ★ }

    • ベストアンサー
    • Java
  • ソケット:書き出しをソケット経由で読み込みできない

    お世話になります。 今、Javaでのソケットプログラミングについて学習をはじめて、はじめてのサンプルプログラムが失敗しました。 そこでもうちょっと簡単にしてみたのですが(一部の抜粋が以下のソースです)、またまたうまくいきません。 エコーサーバのテストなのですが、client : after send messageと表示されたところで処理が止まってしまいます。 結果は最下位に貼り付けてあります。 どうかよろしくお願いします。 // reader/writerの取得 BufferedWriter clientWriter = new BufferedWriter( new OutputStreamWriter(sockClient.getOutputStream()), BUFFERSIZE); BufferedReader clientReader = new BufferedReader( new InputStreamReader(sockClient.getInputStream()), BUFFERSIZE); BufferedWriter serverWriter = new BufferedWriter( new OutputStreamWriter(sockServer.getOutputStream()), BUFFERSIZE); BufferedReader serverReader = new BufferedReader( new InputStreamReader(sockServer.getInputStream()), BUFFERSIZE); // サーバのローカルとクライアントの接続先が同じことの確認 System.out.println("client port : " + sockClient.getPort()); System.out.println("client addr : " + sockClient.getInetAddress().getHostAddress()); System.out.println("server port : " + sockServer.getLocalPort()); System.out.println("server addr : " + sockServer.getLocalAddress().getHostAddress()); // クライアント→サーバー→クライアントの順にmaaaaaいうえおを送信 String strMessage = "maaaaaいうえお"; System.out.println("client : send message : " + strMessage); clientWriter.write(strMessage); System.out.println("client : after send message"); String msgGet = serverReader.readLine(); System.out.println("server : got : " + msgGet); serverWriter.write(msgGet); System.out.println("client : got : " + clientReader.readLine()); ------------以下が結果------------- client port : 4544 client addr : 127.0.0.1 server port : 4544 server addr : 127.0.0.1 client : send message : maaaaaいうえお client : after send message

    • ベストアンサー
    • Java