2017-07-20 18 views
-1

2台のコンピュータ間でメッセージを送信するプログラムを作成しました。メッセージの送信は正常です。しかし、MessageClientクラスからexit()メソッドを呼び出すと、ServerThreadから 'EOF例外'がスローされ、ClientThreadから 'SocketException:Socket Closed'がスローされます。両方のスレッドの 'whileループ'は無限で、exit()メソッドを呼び出すと停止したい。どのように私はこれを修正するのですか?ソケットのデータ入力ストリームからの読み込みを停止したい

メイン:

package team.kha.lan_message; 

import java.util.Scanner; 

public class Main { 
public static void main(String[] args) { 
    Scanner scan; 
    String cmd; 
    while(true){ 
     System.out.print(">> "); 
     scan = new Scanner(System.in); 
     cmd = scan.nextLine(); 

     if(cmd.equals("server")){ 
      new MessageServer(); 
      scan.close(); 
      break; 
     } 
     else if(cmd.equals("client")){ 
      new MessageClient(); 
      scan.close(); 
      break; 
     } 
     else if(cmd.equals("exit")){ 
      scan.close(); 
      break; 
     } 
     else{ 
      System.out.println("Wrong Usage!"); 
      System.out.println("\t Usage: <server> - start [Address] [Port]"); 
      System.out.println("\t Usage: <client> - connect [Address] [Port]"); 
      System.out.println("\t     - send [Message]"); 
      System.out.println("\t     - exit\n"); 
      } 
     } 
    } 
} 

MessageServer:

package team.kha.lan_message; 

import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.net.InetSocketAddress; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.Scanner; 


public class MessageServer { 

Scanner scan; 
String cmd; 
String[] params; 
String ipAddress; 
int port; 
DataInputStream din; 
DataOutputStream dout; 
Socket s; 
ServerSocket ss; 
boolean started = false; 

MessageServer(){ 
    while(true){ 
     System.out.print("(server):"); 
     scan = new Scanner(System.in); 
     cmd = scan.nextLine(); 

     if(!cmd.startsWith(" ")){ 
      params = cmd.split(" "); 

      if(params[0].equals("start") && params.length == 3 && started == false){ 
       startServer(); 
      } 
      else if(params[0].equals("send") && params.length >= 2 && started == true){ 
       sendMessage(); 
      } 
      else if(params[0].equals("exit") && params.length == 1){ 
       exit(); 
       break; 
      } 
     } 
    } 
} 

private void exit() { 
    try { 
     if(started == true){ 
      s.close(); 
      ss.close(); 
     } 
     scan.close(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

private void sendMessage() { 
    String msgout = ""; 

    for(int i = 1 ; i < params.length ;i++){ 
     if(i == params.length-1){ 
      msgout += params[i]; 
     } 
     else{ 
      msgout += params[i] + " "; 
     } 
    } 
    try { 
     dout.writeUTF(msgout); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

private void startServer() { 
    ipAddress = params[1]; 
    port = Integer.parseInt(params[2]); 

    try { 
     ss = new ServerSocket(); 
     ss.bind(new InetSocketAddress(ipAddress , port)); 
     s = ss.accept(); 
     din = new DataInputStream(s.getInputStream()); 
     dout = new DataOutputStream(s.getOutputStream()); 

     new ServerThread(din); 

     started = true; 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } 
    } 
} 

ServerThread:

package team.kha.lan_message; 

import java.io.DataInputStream; 
import java.io.IOException; 

public class ServerThread extends Thread { 

private DataInputStream din; 

ServerThread(DataInputStream din){ 
    this.din = din; 
    start(); 
} 


@Override 
public void run() { 
    while(true){ 
     try { 
      System.out.print("\n(client):"+din.readUTF()+ "\n(server):"); 
     } 
     catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      } 
     } 
    } 



} 

のMessageClient:

package team.kha.lan_message; 

import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.Scanner; 

public class MessageClient { 

Scanner scan; 
String cmd; 
String[] params; 
String ipAddress; 
int port; 
DataInputStream din; 
DataOutputStream dout; 
Socket s; 
boolean connected = false; 

MessageClient(){ 

    while(true){ 
     System.out.print("(client):"); 
     scan = new Scanner(System.in); 
     cmd = scan.nextLine(); 

     if(!cmd.startsWith(" ")){ 
      params = cmd.split(" "); 

      if(params[0].equals("connect") && params.length == 3 && connected == false){ 
       connectServer(); 
      } 
      else if(params[0].equals("send") && params.length >= 2 && connected == true){ 
       sendMessage(); 
      } 
      else if(params[0].equals("exit") && params.length == 1){ 
       exit(); 
       break; 
      } 
     } 
    } 
} 

private void exit() { 
    try { 
     if(connected == true){ 
      s.close(); 
     } 
     scan.close(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

private void sendMessage() { 
    String msgout = ""; 
    for(int i = 1 ; i < params.length ;i++){ 
     if(i == params.length-1){ 
      msgout += params[i]; 
     } 
     else{ 
      msgout += params[i] + " "; 
     } 
    } 
    try { 
     dout.writeUTF(msgout); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

private void connectServer() { 
    ipAddress = params[1]; 
    port = Integer.parseInt(params[2]); 

    try { 
     s = new Socket(ipAddress , port); 

     din = new DataInputStream(s.getInputStream()); 
     dout = new DataOutputStream(s.getOutputStream()); 

     new ClientThread(din); 
     connected = true; 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } 
    } 
} 

クライアントスレッド:

package team.kha.lan_message; 

import java.io.DataInputStream; 
import java.io.IOException; 

public class ClientThread extends Thread{ 

private DataInputStream din; 

ClientThread(DataInputStream din){ 
    this.din = din; 
    start(); 
} 


@Override 
public void run() { 
    while(true){ 
     try { 
      System.out.print("\n(server):"+din.readUTF()+ "\n(client):"); 
     } 
     catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      } 
     } 
    } 

} 
+0

これはスタイルに基づいて読みにくく残念です。まだオブジェクト指向のプログラミングスタイルに慣れていないのは大丈夫ですが、スタティックメソッドを使用し、クラス内のコンストラクタをスキップしてください。 –

+0

なぜ静的メソッドを使用し、コンストラクタをスキップする必要がありますか?私はそうするために、すべてのフィールドとメソッドを静的にする必要があります。あれは正しいですか? –

+0

ちょっとしたことを覚えておいて、あなたが理解してエキスパートになれたら、私のコードを批評し始めることができます:) –

答えて

1

修正する必要はありません。それが起こるはずのものです。過去のストリームの終わりを読んで=>あなたはEOFExceptionを得ます。別にキャッチしてください。break

ループ内のキャッチと無視IOExceptionsはほとんど常に間違っています。接続に致命的でない唯一のものはSocketTimeoutExceptionです。

関連する問題