2016-04-26 18 views
0

私はJavaでサーバークライアントプログラムを持っています。サーバーはいくつかの基本的な計算を行い、結果をクライアントに送信します。その前に、クライアントは操作と値を送信する必要があります。私は正常に1回実行することができますが、私は2番目の操作と値を挿入するときにnullを得る結果があります。なぜこれが起こるのですか?クライアントはサーバーに2回目の実行を送信できません

サーバー

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class Server { 

private static final int PORT = 9001; 

public static void main(String[] args) throws IOException { 
    // TODO Auto-generated method stub 
    System.out.println("O servidor está a correr..."); 
    ServerSocket listener = new ServerSocket(PORT); 
    listener.setSoTimeout(0); 
    try{ 
     while(true){ 
      new Handler(listener.accept()).start(); 
     } 
    }finally{ 
     listener.close(); 
     System.out.println("Servidor fechou!"); 
    } 
} 

private static class Handler extends Thread{ 
    private Socket socket; 
    private BufferedReader in; 
    private PrintWriter out; 

    public Handler(Socket socket){ 
     this.socket = socket; 
    } 

    public void run(){ 
     try{ 
      in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      out = new PrintWriter(socket.getOutputStream(), true); 
      while(true){ 
       String line = in.readLine(); 
       System.out.print(line); 
       double result = parseExecution(line); 
       out.write("" + result + "\n"); 
       out.close(); 
       in.close(); 
      } 
     }catch(IOException e){ 
      e.printStackTrace(); 
     } 
     out.flush(); 


    } 

    private double parseExecution(String line) throws IllegalArgumentException{ 
     // TODO Auto-generated method stub 
       double result = 0; 
       String [] elements = line.split(":"); 
       if (elements.length != 3){ 
        throw new IllegalArgumentException("parsing error!"); 
       } 
       double firstValue = 0; 
       double secondValue = 0; 
       try{ 
        firstValue = Double.parseDouble(elements[1]); 
        secondValue = Double.parseDouble(elements[2]); 
       } catch(Exception e){ 
        throw new IllegalArgumentException("Invalid arguments!"); 
       } 
      switch (elements[0].charAt(0)) { 
      case '+': 
       result = firstValue + secondValue; 
       break; 
      case '-': 
       result = firstValue - secondValue; 
       break; 
      case '*': 
       result = firstValue * secondValue; 
       break; 
      case '/': 
       if(secondValue != 0) 
       result = firstValue/secondValue; 
       break; 
      default: 
       throw new IllegalArgumentException("Invalid math operation!"); 
      } 
      return result; 
     } 
} 
} 

クライアント

import java.io.*; 
import java.net.Socket; 
import java.net.UnknownHostException; 

import javax.swing.JOptionPane; 
import javax.xml.bind.helpers.ParseConversionEventImpl; 

public class MathClient { 

private String getServerAddress(){ 
    return JOptionPane.showInputDialog("Introduza IP do Servidor", JOptionPane.QUESTION_MESSAGE); 
} 

private void run() throws IOException { 
    String serverAddress = getServerAddress(); 
    int port = 9001; 

    // criar a socket 

    Socket socket = new Socket(serverAddress, port); 
    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    BufferedReader op = new BufferedReader(new InputStreamReader(System.in)); 
    BufferedReader valor1 = new BufferedReader(new InputStreamReader(System.in)); 
    BufferedReader valor2 = new BufferedReader(new InputStreamReader(System.in)); 
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 
    while(true){ 
     System.out.println("Operação(+,-,*,/): "); 
     String operacao = op.readLine(); 
     System.out.println("Primeiro valor: "); 
     String primeiroValor = valor1.readLine(); 
     System.out.println("Segundo valor: "); 
     String segundoValor = valor2.readLine(); 
     writer.write(operacao+":"+primeiroValor+":"+segundoValor); 
     writer.newLine(); 
     writer.flush(); 
     //double resultado = Double.parseDouble(reader.readLine()); 
     System.out.println(reader.readLine()); 

    } 

} 

public static void main(String[] args) throws UnknownHostException, IOException { 
    MathClient client = new MathClient(); 
    client.run(); 
} 

} 

ありがとう!

EDIT:run()メソッドの内部私はしばらくのサイクルをしています。しかし、今私はストリーム閉鎖と言っているエラーを取得しています。私がin.close()をwhileサイクルの外に置こうとすると、別のエラーが発生し、in.close()を取り除くことができます。

java.io.IOException: Stream closed 
at java.io.BufferedReader.ensureOpen(Unknown Source) 
at java.io.BufferedReader.readLine(Unknown Source) 
at java.io.BufferedReader.readLine(Unknown Source) 
at MathFinal.Server$Handler.run(Server.java:41) 

ライン41は以下のとおりです。String line = in.readLine();

+0

簡単なご提案です。クライアントはループしていますが、サーバーはループしていません。したがって、サーバーが初めて終了した後に終了することがあります。 – Segmentation

+0

答えをありがとう。私はあなたが言ったことをしたと思うが、今は間違いがある。あなたが見ることができる場合、私はオリジナルの投稿を細部で編集しました。ご協力いただきありがとうございます! – rcrd18

答えて

1

私はあなたのコードを固定し、それは、Java 7のtry-と、リソースを使用して働いています。重要なスニペットは次のとおりです。

private static class Handler extends Thread{ 
    private Socket socket; 

    public Handler(Socket socket){ 
     this.socket = socket; 
    } 

    public void run(){ 
     try(BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) { 
      while(true){ 
       String line = in.readLine(); 
       System.out.print(line); 
       double result = parseExecution(line); 
       out.write("" + result + "\n"); 
       out.flush(); 
      } 
     }catch(IOException e){ 
      e.printStackTrace(); 
     } 

    } 

このようにすると、自分でリソースを閉じることを心配する必要はありません。

+0

ありがとう、それは働いた!あなたが気にしなければ、BufferedWriterとPrintWriterの違いは何かを説明できますか?以前は違いを理解しようとしましたが、できませんでした。 – rcrd18

+0

次回ループを使用しようとしたときにすでに閉じられているため、ループ内のストリームを閉じることはできません。 close操作自体が例外をスローする可能性があるため、リソースを自分で閉じることはJavaでは難しいです。このため、Java 7では、リソースの試行技術を使用するほうが優れています。 –

+0

BufferedWriterはメモリにバッファを使用してストリームに書き込むため、より効率的です。 PrintWriterを使用すると、printlnなどのメソッドを使用して、書式設定されたテキストをストリームに書き込むことができます。 –

関連する問題