客户端无法发送第二次执行到服务器
我有一个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();
我定你的代码,它的工作使用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();
}
}
这样做,你不必担心自己关闭资源。
谢谢,它的工作!如果你不介意,你能解释一下BufferedWriter和PrintWriter之间的区别吗?我试图了解之前的差异,但我不能。 – rcrd18
您无法关闭循环内的流,因为下次尝试使用它们时,它们已经关闭。在Java中自己关闭资源很困难,因为关闭操作本身可能会引发异常。因为Java 7中的这一点最好使用try-with-resources技术。 –
BufferedWriter使用内存中的缓冲区来写入流,所以效率更高。使用PrintWriter,您可以使用println等方法将格式化文本写入流中。 –
只是一个快速的建议。你的客户端运行在一个循环中,但你的服务器不是。所以第一次服务器可能会终止。 – Segmentation
谢谢你的答案。我想我做了你所说的,但现在我得到一个错误。我编辑了我的原始文章的细节,如果你可以看看。谢谢你的帮助! – rcrd18