Java Math Server - 客户端问题

时间:2017-04-19 13:48:36

标签: java netbeans network-programming client-server

我正在为一个项目制作一个简单的Math Server,但在计算结果时遇到了一些困难。我创建了Math服务器,但我知道我的问题来自客户端。

我有4个班,数学服务:

public interface MathService {
 public double add(double firstValue, double secondValue);
 public double sub(double firstValue, double secondValue);
 public double div(double firstValue, double secondValue);
 public double mul(double firstValue, double secondValue);
}

PlainMathService:

public class PlainMathService implements MathService {
 public double add(double firstValue, double secondValue) {
 return firstValue+secondValue;
 }
 public double sub(double firstValue, double secondValue) {
 return firstValue-secondValue;
 }
 public double mul(double firstValue, double secondValue) {
 return firstValue * secondValue;
 }
 public double div(double firstValue, double secondValue) {
 if (secondValue != 0)
 return firstValue / secondValue;
 return Double.MAX_VALUE;
 }
}

MathServer

    public class MathServer{
 protected MathService mathService;
 protected Socket socket;

 public void setMathService(MathService mathService) {
 this.mathService = mathService;
 }
 public void setSocket(Socket socket) {
 this.socket = socket;
 }
 public void execute() {
 try {
 BufferedReader reader = new BufferedReader(
 new InputStreamReader(socket.getInputStream()));
 // read the message from client and parse the execution
 String line = reader.readLine();
 double result = parseExecution(line);
 // write the result back to the client
 BufferedWriter writer = new BufferedWriter(
 new OutputStreamWriter(socket.getOutputStream()));
 writer.write(""+result);
 writer.newLine();
 writer.flush();
 // close the stream
 reader.close();
 writer.close();
 }
 catch (Exception e) {
 e.printStackTrace();
 }
 }
 // the predefined protocol for the math operation is
 // operator:first value:second value
 protected double parseExecution(String line)
 throws IllegalArgumentException {
 double result = Double.MAX_VALUE;
 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 = mathService.add(firstValue, secondValue);
 break;
 case '-':

 result = mathService.sub(firstValue, secondValue);
 break;
 case '*':
 result = mathService.mul(firstValue, secondValue);
 break;
 case '/':
 result = mathService.div(firstValue, secondValue);
 break;
 default:
 throw new IllegalArgumentException("Invalid math operation!");
 }
 return result;
 }
 public static void main(String [] args)throws Exception{
 int port = 80;
 if (args.length == 1) {
 try {
 port = Integer.parseInt(args[0]);
 }
 catch(Exception e){
 }
 }
 System.out.println("Math Server is running...");
 // create a server socket and wait for client’s connection
 ServerSocket serverSocket = new ServerSocket(4444);
 Socket socket = serverSocket.accept();
 // run a math server that talks to the client
 MathServer mathServer = new MathServer();
 mathServer.setMathService(new PlainMathService());
 mathServer.setSocket(socket);
 mathServer.execute();
 System.out.println("Math Server is closed...");
     }
   }

最后,MathClient:

public class MathClient {
 public static void main(String [] args){
 String hostname = "localhost";
 int port = 80;
 if (args.length != 2) {
 System.out.println("Use the default setting...");
 }
 else {
     hostname = args[0];
 port = Integer.parseInt(args[1]);
 }
 try {
 // create a socket
 Socket socket = new Socket(hostname, 4444);

   // object creation handling keyboaard inputs
    BufferedReader input = new BufferedReader(new 
InputStreamReader(System.in));


 String Choice = "a",                    // variable
    firstValue = "45",      // 1st number
    secondValue = "2",      // 2nd number
    defoper = "-",      // default operation
    strResult="";
    // insntiate objects needed to send/receive to/from server
    InputStream in = socket.getInputStream(); //data read from socket
    BufferedReader br = new BufferedReader(new InputStreamReader(in)); //add 
to buffer
    OutputStream out = socket.getOutputStream(); //send data to socket
    PrintWriter pr = new PrintWriter(out, true); //send text

// operations
while (Choice.charAt(0) != 'x')
{
// ui
System.out.println("\n\n      E(x)it from server.\n" +
     "      Press any other key to calculate.  ");
Choice = input.readLine();
if (Choice.equals(""))
     Choice = "a";
switch(Choice.charAt(0))
{
     case 'x':
             pr.println("x");
             break;
     default:
             pr.println("a");
             System.out.print("Enter 1st integer: ");
             firstValue = input.readLine();
             if (firstValue.equals(""))
                     firstValue = "12";
                     System.out.print("Enter 2nd integer: ");
             secondValue = input.readLine();
             if (secondValue.equals(""))
                     secondValue = "2000";
                     System.out.print("Enter your operand: ");
             defoper = input.readLine();
             if (defoper.equals(""))
                     defoper = "+";
             // send the two numbers and the operation to server
             pr.println(firstValue);
             pr.println(secondValue);
             pr.println(defoper);
// read result from server
strResult = br.readLine();
System.out.println(strResult);
             break;
}
}
// close connection
socket.close();
}


 catch (Exception e) {
 e.printStackTrace();
 }}}

问题基本上我可以输入第1和第2个整数,也可以输入opperand,但是一旦我尝试计算这个输入,程序就会崩溃。我对这一发现相当新,令人困惑的是为什么会发生这种情况,但我确定它与客户端有关。感谢

编辑: 崩溃后来自客户端的输出:

run:
Use the default setting...


  E(x)it from server.
  Press any other key to calculate.  

Enter 1st integer: 5

Enter 2nd integer: 1

Enter your operand: *

java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:210)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.readLine(BufferedReader.java:324)
    at java.io.BufferedReader.readLine(BufferedReader.java:389)
    at mathserver.MathClient.main(MathClient.java:80)

崩溃后服务器的输出:

run:
Math Server is running...
java.lang.IllegalArgumentException: parsing error!
Math Server is closed...
    at mathserver.MathServer.parseExecution(MathServer.java:52)
    at mathserver.MathServer.execute(MathServer.java:30)
    at mathserver.MathServer.main(MathServer.java:98)

编辑2:这是我尝试调整以允许用户输入的原始MathClient文件。 (程序使用此文件而不是上面的MathClient工作100%)

public class MathClient {
 public static void main(String [] args){
 String hostname = “localhost”;
 int port = 10000;
 if (args.length != 2) {
 System.out.println(“Use the default setting...”);
 }
 else {
hostname = args[0];
 port = Integer.parseInt(args[1]);
 }
 try {
 // create a socket
 Socket socket = new Socket(hostname, port);
 // perform a simple math operation “12+21”
 BufferedWriter writer = new BufferedWriter(
 new OutputStreamWriter(socket.getOutputStream()));
 writer.write(“+:12:21”);
 writer.newLine();
 writer.flush();
 // get the result from the server
 BufferedReader reader = new BufferedReader(
 new InputStreamReader(socket.getInputStream()));
 System.out.println(reader.readLine());
 reader.close();
 writer.close();
 }
 catch (Exception e) {
 e.printStackTrace();
 }
 }
} 

1 个答案:

答案 0 :(得分:0)

您的问题是进入服务器的输入不符合预期。您正在拆分':',但您没有添加:运算符和操作数之间的字符,因此您的Double.parseDouble调用失败:

try {
 firstValue = Double.parseDouble(elements[1]);
 secondValue = Double.parseDouble(elements[2]);
 }
 catch(Exception e) {
 throw new IllegalArgumentException("Invalid arguments!");
 }

这导致套接字超出范围,因此套接字关闭,并且套接字关闭导致客户端出现异常。

请注意,在许多情况下,SocketExceptions不是问题,因为此功能允许您的读者线程退出它在套接字上等待的read调用。

此外,在您的服务器中,您有

public void execute() {
 try {
 BufferedReader reader = new BufferedReader(
 new InputStreamReader(socket.getInputStream()));
 // read the message from client and parse the execution
 String line = reader.readLine();
 double result = parseExecution(line);
 // write the result back to the client
 BufferedWriter writer = new BufferedWriter(
 new OutputStreamWriter(socket.getOutputStream()));
 writer.write(""+result);
 writer.newLine();
 writer.flush();
 // close the stream
 reader.close();
 writer.close();

您无需关闭阅读器和编写器,因为关闭任何一个将关闭底层套接字。 IMO更清楚地删除最后两行并且只执行socket.close();