• 締切済み

ソケットにおけるメッセージの送受信について

いつもお世話になっています。 ソケットに関して質問します。 下記の手順でソケットを使用したいと考えています。 クラス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 宜しくお願いします。

みんなの回答

回答No.3

askaaskaさんのおっしゃっている通り、基本的な理解が足りないんじゃないですかね。 まず、1~4について主語を付けて整理したらどうでしょう? ----------------------------------------------------- 1)クラスA:ソケット通信でメッセージ送信 2)クラスB:ソケット通信によるメッセージを取得(⇒受信) 3)クラスB:ソケット通信で返信する 4)クラスA:ソケットによるメッセージを再取得する ----------------------------------------------------- 登場人物 : ・クライアントソケット・・・socket = new Socket("localhost", 5555); ・サーバソケット・・・Socket socket = serverSocket.accept(); 動作 : ・書き込む(out) ・読み込む(in) でどうでしょうか。

kannitiha
質問者

お礼

お礼遅くなりました。 かなり、実力不足でした。 いまだに少し理解しきれていませんが、一度試して 再度もう少し勉強しなおしてまた質問させてもらいます。 回答ありがとうございました。 また、よろしくお願いします。

  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.2

これはひどい。 とりあえず、あなたのプログラミングスキルが低いことはわかったわ。 ツッコミどころをいくつか上げていくわね。 1)通信する相手は1つ。つまりSocketのインスタンスは1つあればいいのよ。 2)ストリームは通信開始時に取得して通信終了時に閉じればいいわ。 3)デバッグすれば原因はすぐわかると思うわ。 4)例外発生時はスタットレースを出したほうがいいわよ。それだけでも十分原因が絞り込めるから。 5)staticな変数がどういう意味なのか理解しているかしら?その上でこの実装をしているならいいのだけど。 とりあえずこんなところ。

kannitiha
質問者

お礼

お礼遅くなりました。 一度試して、もう少し勉強しなおしてわからなければ、 再度質問させてもらいます。 回答ありがとうございました。 またよろしくお願いします。

kannitiha
質問者

補足

回答ありがとうございます。 ひとまず、高望みしすぎたので、クラスAから、Messanegerクラスにアクセスする方法を考えて作成し直してみました。 確認してもらえますでしょうか? public class Messanger { private ServerSocket serverSocket; private Socket socket; private PrintWriter writerOut; private BufferedReader in; //socketを解放 public void openSocket() { System.out.println( "--- openSocket -- "); try { //serverSocket = new ServerSocket(5555); //一回起動させたら、以降表示しない socket = new Socket("localhost", 5555); } catch (UnknownHostException e) { System.out.println( e.getStackTrace() ); } catch (IOException e) { System.out.println( e.getStackTrace() ); } } //socketを閉じる public void closeSocket() { try { in.close(); writerOut.close(); socket.close(); serverSocket.close(); } catch (IOException e) { System.out.println( e.getStackTrace() ); } } //メッセージ送信 public void sendMsg(String message ) { try{ //socketの接続状態 System.out.println("接続の有無 _ :" + this.socket.isConnected() ); // 出力ストリームを取得 writerOut = new PrintWriter(socket.getOutputStream(), true); //出力 writerOut.println(message); System.out.println(message); } catch (IOException e) { System.out.println( "send-IO:"+e.getStackTrace() ); } catch(NullPointerException e) { System.out.println( e.getStackTrace() ); } } //メッセージ取得 public String getMsg() { System.out.println( "return _getMsg_ :" + socket.isConnected() ); String message = ""; try{ // 入力ストリームを取得 in = new BufferedReader( new InputStreamReader( this.socket.getInputStream())); //戻り値に入力 message = in.readLine(); } catch (IOException e) { System.out.println(e.getStackTrace()); } catch(NullPointerException e){ System.out.println(e.getStackTrace()); } System.out.println("message_return:"+ message); return message; } } ◆ ----- 実行するクラス ----◆ public class TestMsg { public static void main(String[] args) { Messanger msn = new Messanger(); msn.openSocket(); msn.sendMsg("メッセージ送信test! "); String returnMsg = msn.getMsg(); System.out.println( "ソケット通信されたmessage:" + returnMsg ); msn.closeSocket(); } } ◆ ---- コンソール表示 -----◆ --- openSocket -- 接続の有無 _ :true メッセージ送信test! return _getMsg_ :true このとき、どうしても、値を取り出せないのですが、やはり原因は確実に【PrintWriterで出力されていない】からなのでしょうか? 宜しくお願いします。

  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.1

勘違い発見。 × クラスB:ソケット通信によるメッセージを取得 ○ クラスB:ソケット通信によるメッセージを受信 それはさておき やりたいことは HelloWorldSocketServerとHelloWorldSocketClientを 1つのクラスで書いちゃおうてことよね。 そうすれば2台のパソコンで同じクラスを実行すればよくなるから。 「うまくいかない」がどのように失敗しているのかわからないけど 多分あなたは、その参考にしているページに書かれている HelloWorldSocketServerとHelloWorldSocketClientのコードが 理解できていないんだと思うわ。 わかっていたら少なくともあっちこちに out=、in=は記述しないはずよ。 この2つのクラスは片方だけでソケットの送信と受信、両方とも行っているのよ。 inとoutの順序が逆なだけ。 もう一回言うわよ? inとoutの順序が逆なだけ。 大事なので2回言ったわ。 このinから読み込むのがあなたの言うgetMsg、 outに書き込むのがsetMsgよ。 何か余計な処理をしているってこと気づけるかしら。

kannitiha
質問者

補足

回答ありがとうございます。 再度確認してみました。 out/inの意味はなんとか理解できたのですが、 socketから取り出す場合がどうも上手くいきません。 以下が修正ソースです。 public class Messaneger { private static Socket socket; private static BufferedReader in; //ソケットを開く public static void openSocket() { ServerSocket serverSocket; try { serverSocket = new ServerSocket(5555); System.out.println("クライアントからの接続をポート5555で待ちます"); // クライアントからの接続を待ちます Socket socket = serverSocket.accept(); System.out.println(socket.getInetAddress() + "から接続を受付ました"); } catch (IOException e) {} } /** * ソケット通信でメッセージを送信 * @param 送信するメッセージ */ public static void setMsg(String sendMsg) { try { socket = new Socket("localhost", 5555); // 入力 PrintWriter out = new PrintWriter(socket.getOutputStream(), true); //メッセージ設定 out.println( sendMsg ); in = new BufferedReader( new InputStreamReader( socket.getInputStream())); //送信メッセージdata // System.out.println(sendMsg); } catch (IOException e) {} } /** * ソケット通信でメッセージを取得 * @return msg サーバーに渡されたメッセージ */ public static String getMsg() { String getMsg = ""; //このとき上手くメッセージが取り出せない try { String inputLine = null; //取り出し用の、inを設定する in = new BufferedReader( new InputStreamReader( socket.getInputStream())); while (inputLine != in.readLine()) { System.out.println("AA:"+in.readLine()); } } catch (IOException e) {} return getMsg; } } 宜しくお願いします。

関連するQ&A

専門家に質問してみよう