質問
大学の課題でJAVAのサーバ・クライアントプログラムを作成しています。
サーバとクライアントの接続切れの判定について、理解の難しい挙動があったため質問いたします。このような挙動がなぜ起こるのかをご教授いただきたいです。
java
1import java.io.BufferedReader; 2import java.io.IOException; 3import java.io.InputStreamReader; 4import java.io.PrintWriter; 5import java.net.Socket; 6import java.net.UnknownHostException; 7 8public class SimpleClient { 9 10 public static void main(String[] args) { 11 Socket s; 12 try { 13 s = new Socket("localhost", 10000);//パソコン2台のときは"localhost"を"192.168."から始まるプライベートIPアドレスに 14 PrintWriter out = new PrintWriter(s.getOutputStream(), true); 15 InputStreamReader sisr = new InputStreamReader(s.getInputStream()); 16 BufferedReader br_in = new BufferedReader(sisr); 17 BufferedReader br_out = new BufferedReader(new InputStreamReader(System.in), 1); 18 while(true) { 19 System.out.println("サーバへの入力"); 20 out.println(br_out.readLine()); 21 //System.out.println("サーバからの出力"); 22 //System.out.println(br_in.readLine()); 23 } 24 25 } catch (UnknownHostException e) { 26 // TODO 自動生成された catch ブロック 27 e.printStackTrace(); 28 } catch (IOException e) { 29 // TODO 自動生成された catch ブロック 30 e.printStackTrace(); 31 } //サーバ(ipAddress, port)に接続 32 33 34 } 35 36}
上記のようなクライアントプログラムと、以下のようなサーバプログラムで、br.readLine()がIOExceptionを投げるかどうかでクライアントとの接続切れを判定していました。
java
1import java.io.BufferedReader; 2import java.io.IOException; 3import java.io.InputStreamReader; 4import java.net.ServerSocket; 5import java.net.Socket; 6 7public class Servertest { 8 public static void main(String[] args){ 9 ServerSocket ss; 10 try { 11 ss = new ServerSocket(10000); 12 Socket socket = ss.accept(); 13 InputStreamReader sisr = new InputStreamReader(socket.getInputStream()); 14 BufferedReader br = new BufferedReader(sisr); 15 while(true) {// データを受信し続ける 16 String inputLine; 17 inputLine = br.readLine(); 18 System.out.println(inputLine); 19 } 20 } catch (IOException e1) { 21 // TODO 自動生成された catch ブロック 22 e1.printStackTrace(); 23 } 24 } 25 26}
しかし、一つのパソコンでサーバとクライアントのプログラムを起動したときはうまくいったのですが、サーバとクライアントを別のパソコンで起動したときは**br.readLine()**が例外を投げずに、nullを返してそのまま処理が続行してしまいました。
発生している問題・エラーメッセージ
localhostで実行した場合は、クライアントのコマンドプロンプトでctrl+Cを押して、クライアントプログラムを終了すると、以下のように例外を投げます
java.net.SocketException: Connection reset at java.base/java.net.SocketInputStream.read(SocketInputStream.java:186) at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140) at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) at java.base/java.io.InputStreamReader.read(InputStreamReader.java:185) at java.base/java.io.BufferedReader.fill(BufferedReader.java:161) at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326) at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392) at server.Servertest.main(Servertest.java:19)
しかしながら、2台のパソコンの時は、上記のように例外が投げられず、nullが無限ループで表示されました。
どうして、このような挙動になるのか教えていただけると幸いです
補足情報(FW/ツールのバージョンなど)
サーバとクライアントを同じパソコンの時は
サーバ:windows(Eclipse、openjdk11)
クライアント:windows(コマンドプロンプト、openjdk11)
サーバとクライアントを別のパソコンにしたときは
サーバ:windows(Eclipse、openjdk11)
クライアント:Mac(ターミナル、java 14.0.2)
で、Wifiのローカルネットワークで通信しました。
あなたの回答
tips
プレビュー