質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

Q&A

解決済

1回答

3931閲覧

ソケット通信を複数回行った時処理が行われない

yukkuri

総合スコア624

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

0グッド

0クリップ

投稿2018/12/26 12:56

前提・実現したいこと

現在、Javaでソケット通信を行っていました。

発生している問題・エラーメッセージ

エラーメッセージは出ていない 2度同じサーバーにアクセスしたら実行結果が出ない

該当のソースコード

Java

1package org.jyl.base; 2 3public interface SocketUtil 4{ 5 public void down(); 6 7 public boolean isConnect(); 8 9 public String receive() throws JylException; 10 11 public boolean send( String message ); 12 13 public boolean setUp(); 14}
package org.jyl.base; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; public class JylClient implements Runnable, SocketUtil { private boolean connect = false; private Socket sc = null; private BufferedReader br = null; private PrintWriter pw = null; public JylClient( final String HOST, final int PORT ) throws JylException { try{ sc = new Socket( HOST, PORT ); }catch( IOException ie ){ try{ if( sc != null ) sc.close(); }catch( IOException ie2 ){ throw new JylException( ie2 ); } } } @Override public void down() { if( br != null ) br = null; if( pw != null ) pw = null; if( sc != null ) sc = null; connect = false; } @Override public boolean isConnect() { return connect; } @Override public String receive() throws JylException { if( br == null || sc == null ) return ""; String str = ""; try{ str = br.readLine(); }catch( IOException ie ){ throw new JylException( ie ); } return str; } @Override public boolean send( String message ) { if( pw == null || sc == null ) return false; pw.println( message ); pw.flush(); return true; } @Override public boolean setUp() { try{ // 実装の都合上バッファをクリアのみ br = new BufferedReader( new InputStreamReader( sc.getInputStream() ) ); pw = new PrintWriter( new BufferedWriter( new OutputStreamWriter( sc.getOutputStream() ) ) ); Thread th = new Thread( this ); th.start(); connect = true; }catch( IOException ie ){ connect = false; } return isConnect(); } @Override public void run(){} }
package org.jyl.base; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class JylServer implements Runnable, SocketUtil { private boolean connect = false; // 接続できたか isConnect() private ServerSocket ss = null; private Socket sc = null; private BufferedReader br = null; // クライアントからのデータを受け取るバッファ private PrintWriter pw = null; // サーバーから送るデータのバッファ public JylServer( final int PORT ) throws JylException { try{ ss = new ServerSocket( PORT ); }catch( IOException ie ){ try{ if( ss != null ) ss.close(); }catch( IOException ie2 ){ throw new JylException( ie2 ); } } } @Override public void down() { // この関数実行後に送ったりしようとするとエラーになるようにしている if( br != null ) br = null; if( pw != null ) pw = null; if( sc != null ) sc = null; if( ss != null ) ss = null; connect = false; } @Override public boolean isConnect() { return connect; } @Override public String receive() throws JylException { if( br == null || sc == null ) return ""; String str = ""; try{ str = br.readLine(); }catch( IOException ie ){ throw new JylException( ie ); } return str; } @Override public boolean send( String message ) { if( pw == null || sc == null ) return false; pw.println( message ); pw.flush(); return true; } @Override public boolean setUp() { while( !isConnect() ){ try{ sc = ss.accept(); // 接続されるまで待つ // 読み込み、書き込みバッファーを用意 br = new BufferedReader( new InputStreamReader( sc.getInputStream() ) ); pw = new PrintWriter( new BufferedWriter( new OutputStreamWriter( sc.getOutputStream() ) ) ); Thread th = new Thread( this ); th.start(); connect = true; }catch( IOException ie ){ connect = false; } } return isConnect(); } @Override public void run(){} }

テストクラス

package org.jyl.base.test; import org.jyl.base.JylClient; import org.jyl.base.JylException; public class JylClientTest extends JylClient { public static final String HOST = "localhost"; public static final int PORT = 10000; public static void main( String[] args ) { try{ new JylClientTest(); }catch( JylException e ){ e.printStackTrace(); } } public JylClientTest() throws JylException { super( HOST, PORT ); System.out.println( "接続を開始します..." ); setUp(); } @Override public void run() { try{ while( true ){ System.out.println( receive() ); } }catch( JylException e ){ e.printStackTrace(); } } }
package org.jyl.base.test; import org.jyl.base.JylException; import org.jyl.base.JylServer; public class JylServerTest extends JylServer { public static final int PORT = 10000; public static void main( String[] args ) { try{ new JylServerTest(); }catch( JylException e ){ e.printStackTrace(); } } public JylServerTest() throws JylException { super( PORT ); System.out.println( "接続を開始します..." ); setUp(); } @Override public void run() { while( true ) send( "Hello Server!" ); } }

試したこと

ソケット通信について調べてみた
デバッグ用メッセージを設置して実行してみた
Findbugs(プラグイン)でバグ検索をしてみた

サーバーを初期化しなければいけない?

補足情報(FW/ツールのバージョンなど)

eclipseの3.8を使用しています。
OSはlinux系統です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

JylServerクラスのsetUpメソッド内においてsc = ss.accept();でクライアントからの接続後、connect = true; としている為に冒頭のwhile( !isConnect() )falseと評価して抜け、結果として1回の接続で終わってしまっていませんか。

sc = ss.accept();の後にそのクライアントのソケットscをもってスレッド内で単独で処理をさせるかまたは、スレッドではなく、接続済みのクライアントとの処理が終わるまでは別のクライアントの接続を保留(実質、接続不可)しなければなりません。

ご提示の現状のコードではSocket scはクラス中の単独のインスタンス変数になっているために複数のスレッドが起動した場合に上書きされてしまいます。スレッドを使って複数のクライアントの同時接続を可能とするのか、それともスレッドを使わないで逐次のクライアント接続とするのか、両方の意識が混在したコードとなっているように見受けられます。

また、今回のご質問の本題とは離れますが、Socket scはクライアントとの送受信が終わった後にcloseすべきでしょう。

投稿2018/12/26 15:28

dodox86

総合スコア9181

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問