2016-04-26 116 views
0

我有一個Java中的服務器客戶端程序。服務器進行一些基本計算並將結果發送給客戶端。在此之前,客戶必須發送操作和值。我可以成功運行一次,但是當我插入第二個操作和值時,我得到null有一個結果。爲什麼會發生?客戶端無法發送第二次執行到服務器

服務器

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(); 
} 

} 

謝謝!

編輯︰內部run()方法我正在做一個while循環。但是現在我收到一條錯誤,說流關閉。當我試圖在週期外放in.close()時,它給了我另一個錯誤並刪除了in.close()。 41

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) 

線爲: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

您無法關閉循環內的流,因爲下次嘗試使用它們時,它們已經關閉。在Java中自己關閉資源很困難,因爲關閉操作本身可能會引發異常。因爲Java 7中的這一點最好使用try-with-resources技術。 –

+0

BufferedWriter使用內存中的緩衝區來寫入流,所以效率更高。使用PrintWriter,您可以使用println等方法將格式化文本寫入流中。 –

相關問題