我正在为一个项目制作一个简单的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();
}
}
}
答案 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();