• ベストアンサー

Socket プログラミングについて

先日の質問ではありがとうございました。 今回はソースコードについてですが もしよろしければアドバイスお願いします。 Socket 制御を行うアプリを作成しています。 ・クライアントアプリ ・サーバアプリ の2つから構成していまして同PC上で動作させます。 クライアントから localhost 経由でサーバアプリに接続。 サーバアプリは ServerSocket を生成して accept しています。 サーバアプリで accept により Socket を生成すると その Socket を Thread に引き渡して適宜処理を行います。 その後、 再び別クライアントからの接続を待つために サーバアプリで accept したいのですが そのまま accept を呼び出しても そこで待機せずに新しい Socket を生成しています。 別クライアントからの接続を待機するにはどうしたらいいのでしょうか? ご教授お願いします。

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

  • ベストアンサー
回答No.1

JavaDocより acceptは接続要求を待機すると書いてあります。 私もたまにソケット接続するアプリを作成しますが、特別なことはしていません。 問題があるとすればアプリケーション自体の作りの方かな?と思います。

参考URL:
http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/java/net/ServerSocket.html#accept()
Zepetto
質問者

お礼

ありがとうございます。 JavaDocの方も何でも見てみましたが未だ解決に至らずです。 ソースはこんな感じになってます。 コメントや余分なところは削除したものになります。 どこかおかしいでしょうか? ○クライアント public void actionPerformed(java.awt.event.ActionEvent e) { try { Socket socket = new Socket("localhost", 7144); InputStream sin = socket.getInputStream(); OutputStream sout = socket.getOutputStream(); sout.write( SetConnect, 0, SetConnect.length ); sout.close(); sin.close(); socket.close(); } catch(Exception eExcep){ eExcep.printStackTrace(); } } ○サーバ public class ServerThread extends Thread{ Socket socket; public void run(){ try { ManagementThread mngThread = new ManagementThread(); ServerSocket svsock = new ServerSocket(7144); while(true) { try { Socket socket = svsock.accept(); AppliThread thAppli = new AppliThread(); thAppli.socket = socket; thAppli.start(); DeviceSetting wkDevSet = new DeviceSetting(); TargetThread thTarget = new TargetThread(wkDevSet); thTarget.start(); mngThread.AppendObjAppli( thAppli ); mngThread.AppendObjTarget( thTarget ); } catch (Exception ex) { ex.printStackTrace(); } } } catch (IOException e) { e.printStackTrace(); } } } public class AppliThread extends Thread{ Socket socket; byte RecvData[] = new byte[4095]; public void run(){ try { InputStream sin = socket.getInputStream(); OutputStream sout = socket.getOutputStream(); while(true) { sin.read(RecvData); sin.close(); sout.close(); socket.close(); } } catch (IOException e) { e.printStackTrace(); } } }

その他の回答 (2)

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.3

かなりいろいろむちゃくちゃな部分があるので、説明は略して、クライアント/サーバの基本形を下に示します。参考になれば幸いです。 ------------------------------------------------------ //クライアント    public void actionPerformed(java.awt.event.ActionEvent e) {     connectButton.setEnabled(false);     Thread t = new Thread(new Runnable(){      public void run(){       try {        Socket socket = new Socket("localhost", 7144);        InputStream sin = socket.getInputStream();        OutputStream sout = socket.getOutputStream();        sout.write(setConnect, 0, setConnect.length);        sout.close();        sin.close();        socket.close();       }       catch(Exception eExcep){        eExcep.printStackTrace();       }       finally{        SwingUtilities.invokeLater(new Runnable(){         public void run(){          connectButton.setEnabled(true);         }        });       }      }     });     t.start();    } //サーバ public class Server{  ServerSocket svsock;  public Server(){ //本当はコンストラクタの中でここまではしない   try { //今回はあくまでも簡単な例示として見てください    svsock = new ServerSocket(7144);    while(true) {     try {      Socket socket = svsock.accept();      new Thread(new Appli(socket)).start();     }     catch (Exception ex) {      ex.printStackTrace();     }    }   }   catch (IOException e) {    e.printStackTrace();   }  } } class Appli implements Runnable{  Socket socket;  byte recvData[];  public Appli(Socket s){   socket = s;   recvData = new byte[4095];  }  public void run(){   try {    InputStream sin = socket.getInputStream();    OutputStream sout = socket.getOutputStream();    sin.read(recvData);    sin.close();    sout.close();    socket.close();   }   catch (IOException e) {    e.printStackTrace();   }  } } ------------------------------------------------

参考URL:
http://java.sun.com/docs/books/tutorial/networking/sockets/index.html
Zepetto
質問者

お礼

ありがとうございます。 そして遅くなり申し訳ありません。 サンプルソースありがとうございます。 参考にさせていただきます。

回答No.2

このソースでエラーなく実行できるようには思えないです。 サーバ側のAppliThreadスレッド内の無限ループとか。。。 今ちょっといじって動くものにしてみました。 実行結果は、やはりクライアントを立ち上げる度にacceptを抜けるようです。 クライアントはGUIアプリのようですが、actionPerformedがたくさん呼ばれてたりしませんか? public class Main { public static void main(String[] args) { try { Socket socket = new Socket("localhost", 7144); InputStream sin = socket.getInputStream(); OutputStream sout = socket.getOutputStream(); sout.write("あいうえお".getBytes(), 0, "あいうえお".getBytes().length ); sout.close(); sin.close(); socket.close(); } catch(Exception eExcep){ eExcep.printStackTrace(); } } } public class ServerMain { public static void main(String[] args) { try { ServerSocket svsock = new ServerSocket(7144); while (true) { try { Socket socket = svsock.accept(); System.out.println("accept!:" + socket); AppliThread thAppli = new AppliThread(); thAppli.socket = socket; thAppli.start(); } catch (Exception ex) { ex.printStackTrace(); } } } catch (IOException e) { e.printStackTrace(); } } } class AppliThread extends Thread { Socket socket; byte RecvData[] = new byte[10]; public void run() { try { InputStream sin = socket.getInputStream(); OutputStream sout = socket.getOutputStream(); sin.read(RecvData); sin.close(); sout.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }

Zepetto
質問者

お礼

返信ありがとうございます。 そして遅くなって申し訳ありません。 元ソースから削って載せたので 変に無限ループだったり 見苦しいソースですみません(汗) クライアント側については ステップして見てるのですが actionPerformed が何度も呼ばれてるようなことは ないように思います。 引き続き調べてみます。

関連するQ&A