Im making a simple Math Server for a project but im coming into some difficulties, when calculating the result. I have created the Math server but i know my problems are coming from the client side.
I have 4 classes, Math Service:
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...");
}
}
and finally, 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();
}}}
The problem is basically i can enter in the 1st and 2nd integer, and also the opperand, but once i try and calculate this input, the program crashes. Im fairly new to this finding it confusing as to why this is happening, but im certain its to do with the client side. Thanks
Edit:
Output from Client after crashing :
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)
Output from server after crashing:
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)
EDIT 2: Here is the original MathClient file which i have tried to adapt to allow user input. (program works 100% with this file instead of above MathClient)
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();
}
}
}
Your problem is that the input coming into your server is not what is expected. You are splitting on ':', but you are not adding : characters between your operators and operands, so your Double.parseDouble call is failing here:
try {
firstValue = Double.parseDouble(elements[1]);
secondValue = Double.parseDouble(elements[2]);
}
catch(Exception e) {
throw new IllegalArgumentException("Invalid arguments!");
}
This is causing your socket to go out of scope, so the socket closes, and that socket closure is causing the exception on your client side.
Be aware that SocketExceptions in many cases, are NOT A PROBLEM, as this functionality allows your reader thread to get out of a read call that it's waiting on the socket for.
Also, in your server, where you have
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();
You do not need to close both the reader and the writer, as closing either one will close the underlying socket. IMO it is clearer to remove these last two lines and just do socket.close();
Related
I am creating a Socket Client/Sever program that outputs the results of a fibonacci formula. I have already built the client/server connection and have tested. That part of it is working as intended. I am now trying to add in the fibonacci formula to the server but am having trouble coding the conversion of int type toSring(). The fibonacci formula is running on the server side. Code will be posted below. Thank you all for the help. I am trying to pass the clients input into fibonacci(int n) to get the desired results. If the user inputs 2, the answer should be 3, since 2 + 1 = 3 in the fibonacci numbering sequence.
Server Code:
public class ServerData {
public static int fibonacci(int n) {
int v1 = 0, v2 = 1, v3 = 0;
for(int i = 2; i <= n; i++) {
v3 = v1 + v2;
v1 = v2;
v2 = v3;
}
return v3;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ServerSocket server = null;
boolean shutdown = false;
try {
server = new ServerSocket(1236);
System.out.println("Port bound. Accepting connection");
} catch(IOException e) {
e.printStackTrace();
System.exit(-1);
}
while(!shutdown) {
Socket client = null;
InputStream input = null;
OutputStream output = null;
try {
client = server.accept();
input = client.getInputStream();
output = client.getOutputStream();
int n = input.read();
byte[] data = new byte[n];
input.read(data);
// int fibOut = fibonacci(int n);
String clientInput = new String (data, StandardCharsets.UTF_8);
clientInput.replace("\n","");
System.out.println("Client said: " + clientInput);
String response = ("Your input was [" + clientInput + "]");
output.write(response.length());
output.write(response.getBytes());
client.close();
if(clientInput.equalsIgnoreCase("shutdown")) {
System.out.println("shutting down...");
shutdown = true;
}
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
}
}
Client Code:
public class ClientData {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.print("Input a String: ");
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
try {
String userString = userInput.readLine();
Socket connection = new Socket("127.0.0.1", 1236);
InputStream input = connection.getInputStream();
OutputStream output = connection.getOutputStream();
output.write(userString.length());
output.write(userString.getBytes());
int n = input.read();
byte [] data = new byte[n];
input.read(data);
String serverResponse = new String(data, StandardCharsets.UTF_8);
System.out.println("Server said: " + serverResponse);
if (!connection.isClosed());
connection.close();
}
catch (IOException e ) {
e.printStackTrace();
}
}
}
If you want to send data between client and server as text, then what you need to do on the server side (after reading from input into byte[]) is to convert it into String and then parse as int.
That you can do with int number = Integer.parseInt(new String(data));.
However, your code has one more bug (in both client and server).
It's in the code that is writing string into the output stream.
Your code is doing following thing:
output.write(userString.length());
output.write(userString.getBytes());
which may give invalid results. Notice that length() returns length of the String, which means: number of characters.
However what you need is number of bytes. Those two values will be different in case your string contains characters from outside of ascii range.
i have a very simple assignment in which i am supposed to send 2 integers into a socket, which sends their sum back to the "client".
this is my client:
int a,b,sum;
try
{
Socket Server_info = new Socket ("localhost", 15000);
BufferedReader FromServer = new BufferedReader (new InputStreamReader(Server_info.getInputStream()));
DataOutputStream ToServer = new DataOutputStream(Server_info.getOutputStream());
while (true)
{
System.out.println("Type in '0' at any point to quit");
System.out.println("Please input a number");
a = User_in.nextInt();
ToServer.writeInt(a);
System.out.println("Please input a second number");
b = User_in.nextInt();
ToServer.writeInt(b);
sum = FromServer.read();
System.out.println("the sum of " +a+ " and " +b+ " is: " +sum );
if (a==0 || b==0)
break;
}
this is my socket handler:
int num1=0 ,num2=0, sum;
try
{
BufferedReader InFromClient = new BufferedReader (new InputStreamReader(soc_1.getInputStream()));
DataOutputStream OutToClient = new DataOutputStream(soc_1.getOutputStream());
while (true)
{
num1 = InFromClient.read();
num2 = InFromClient.read();
sum = num1 + num2 ;
OutToClient.writeInt(sum);
}
}
catch (Exception E){}
After the first Integer input upon running the client i get this:
Type in '0' at any point to quit
Please input a number
5
Connection reset by peer: socket write error
i think the problem lays at the socket receiving side, i must be doing something wrong. any suggestions?
You can use DataInputStream and DataOupStream objects but I find it simpler to user a pair of Scanner and PrintWriter objects both at the server side and client side. So here is my implementation of the solution to the problem:
The Server Side
import java.io.*;
import java.net.*;
import java.util.*;
public class TCPEchoServer {
private static ServerSocket serverSocket;
private static final int PORT = 1234;
public static void main(String[] args)
{
System.out.println("Opening port...\n");
try {
serverSocket = new ServerSocket(PORT);
}
catch (IOException ioex){
System.out.println("Unable to attach to port!");
System.exit(1);
}
handleClient();
}
private static void handleClient()
{
Socket link = null; //Step 2
try {
link = serverSocket.accept(); //Step 2
//Step 3
Scanner input = new Scanner(link.getInputStream());
PrintWriter output = new PrintWriter(link.getOutputStream(), true);
int firstInt = input.nextInt();
int secondInt = input.nextInt();
int answer;
while (firstInt != 0 || secondInt != 0)
{
answer = firstInt + secondInt;
output.println(answer); //Server returns the sum here 4
firstInt = input.nextInt();
secondInt = input.nextInt();
}
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
System.out.println("Closing connection...");
link.close();
}
catch (IOException ie)
{
System.out.println("Unable to close connection");
System.exit(1);
}
}
}
}
The Client Side
import java.net.*;
import java.io.*;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class TCPEchoClient {
private static InetAddress host;
private static final int PORT = 1234;
public static void main(String[] args) {
try {
host = InetAddress.getLocalHost();
} catch (UnknownHostException uhEx) {
System.out.println("Host ID not found!");
System.exit(1);
}
accessServer();
}
private static void accessServer() {
Socket link = null; //Step 1
try {
link = new Socket(host, PORT); //Step 1
//Step 2
Scanner input = new Scanner(link.getInputStream());
PrintWriter output = new PrintWriter(link.getOutputStream(), true);
//Set up stream for keyboard entry
Scanner userEntry = new Scanner(System.in);
int firstInt, secondInt, answer;
do {
System.out.print("Please input the first number: ");
firstInt = userEntry.nextInt();
System.out.print("Please input the second number: ");
secondInt = userEntry.nextInt();
//send the numbers
output.println(firstInt);
output.println(secondInt);
answer = input.nextInt(); //getting the answer from the server
System.out.println("\nSERVER> " + answer);
} while (firstInt != 0 || secondInt != 0);
} catch (IOException e) {
e.printStackTrace();
}
catch (NoSuchElementException ne){ //This exception may be raised when the server closes connection
System.out.println("Connection closed");
}
finally {
try {
System.out.println("\n* Closing connection… *");
link.close(); //Step 4.
} catch (IOException ioEx) {
System.out.println("Unable to disconnect!");
System.exit(1);
}
}
}
}
The problem is that you mix streams and readers.
In order to successfully pass integers from client to server, for example with Data[Input/Output]Stream you should use:
// Server side
final DataInputStream InFromClient = new DataInputStream(soc_1.getInputStream());
final DataOutputStream OutToClient = new DataOutputStream(soc_1.getOutputStream());
// than use OutToClient.writeInt() and InFromClient.readInt()
// Client side
final DataInputStream FromServer = new DataInputStream(Server_info.getInputStream());
final DataOutputStream ToServer = new DataOutputStream(Server_info.getOutputStream());
// than use ToServer.writeInt() and FromServer.readInt()
If you let's say send an int from client to server (in this case using DataOutputStream.writeInt), it is very important to read the data with the corresponding decoding logic (in our case DataInputStream.readInt).
I'm trying to send a message to a particular client e.g. client 1 wants to send a message to client 2. Client 1 sends a message to the sever, the sever computes the answer and sends it to client 2 who displays it.
I'm using a HashMap to store each client. It compiles, but when I run it, it crashed when sending the message and displays
Problem with Communication Server
I believe the error is in the loop where I'm sending the message but I can't see what's wrong with it, do I need separate code on the client side?
Server:
import java.net.*;
import java.util.*;
import java.io.*;
public class EchoServer2b extends Thread implements Runnable{
protected static Socket clientSocket;
static String [] logs = new String[100];
//protected static ArrayList<PrintWriter> writers = new ArrayList<PrintWriter>();
static HashMap<String, Socket> clients = new HashMap<String, Socket>();
static int arrayPos = 0;
static int i, clientCount = 0;
static String clientID;
static String receiver="",actualMessage="";
public static void main(String[] args) throws IOException{
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(10008);
System.out.println ("Connection Socket Created");
try {
while (true)
{
System.out.println ("Waiting for Connection");
new EchoServer2b (serverSocket.accept());
++clientCount;
clientID = Integer.toString(clientCount);
clients.put(clientID, clientSocket);
}
}
catch (IOException e)
{
System.err.println("Accept failed.");
System.exit(1);
}
}
catch (IOException e)
{
System.err.println("Could not listen on port: 10008.");
System.exit(1);
}
finally{
try{
serverSocket.close();
}
catch (IOException e)
{
System.err.println("Could not close port: 10008.");
System.exit(1);
}
}
}
private EchoServer2b (Socket clientSoc){
clientSocket = clientSoc;
start();
}
public void run(){
System.out.println ("New Communication Thread Started");
try{
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("Client ID: " + clientID);
String inputLine;
while ((inputLine = in.readLine()) != null) { //reading
System.out.println(inputLine);
String message[]=inputLine.split(", ");
logs[arrayPos] = message[1]; //keep record of all commands sent to server
arrayPos++; //update array position
receiver=message[0];
actualMessage=message[1];
if (actualMessage.equals("Bye.")) //break if client enters 'Bye."
break;
if(actualMessage.equals("Logs.")){ //print out contents of logs if any client enters 'Logs'
for(i=0; i<arrayPos; i++){
System.out.println("Log"+ i + ": " + logs[i]);
}
break;
}
for (Map.Entry<String, Socket> entry: clients.entrySet()) {
String clientName = entry.getKey();
if(clientName.equals(receiver))
{
Socket socket = entry.getValue();
try {
PrintWriter receiverOut = new PrintWriter(socket.getOutputStream(), true);
//DataOutputStream receiverDOS = new DataOutputStream(socket.getOutputStream());
int x, y, result;
String num1, num2, operator;
String [] splitStrings = actualMessage.split(" ");
num1 = splitStrings[0];
x = Integer.parseInt(num1);
operator = splitStrings[1];
num2 = splitStrings[2];
y = Integer.parseInt(num2);
switch(operator){
case "+":
result = x + y;
System.out.println ("Server: " + result);
receiverOut.println(result);
break;
case "-":
result = x - y;
System.out.println ("Server: " + result);
receiverOut.println(result);
break;
case "*":
result = x * y;
System.out.println ("Server: " + result);
receiverOut.println(result);
break;
case "/":
result = x / y;
System.out.println ("Server: " + result);
receiverOut.println(result);
break;
default:
System.out.println("Please enter a more simple equation using one of the 4 main operators i.e. '+, -, *, /'");
break;
}
receiverOut.flush();
receiverOut.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
out.flush();
out.close();
in.close();
clientSocket.close();
}
catch (IOException e){
System.err.println("Problem with Communication Server");
e.printStackTrace();
System.exit(1);
}
}
public void sendMessage(String receiver, String actualMessage) {
}
}
Client:
import java.io.*;
import java.net.*;
public class EchoClientB {
static boolean flag = true;
public static void main(String[] args) throws IOException{
String serverHostname = new String ("127.0.0.1");
if (args.length > 0)
serverHostname = args[0];
System.out.println ("Attemping to connect to host " + serverHostname + " on port 10008.");
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try{
echoSocket = new Socket(serverHostname, 10008);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
}catch (UnknownHostException e){
System.err.println("Don't know about host: " + serverHostname);
System.exit(1);
} catch (IOException e){
System.err.println("Couldn't get I/O for " + "the connection to: " + serverHostname);
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String userInput = "";
System.out.println ("Type Message (\"Bye.\" to quit)");
//System.out.println("Enter a simple math equation i.e. 2 + 2 separated by a space…");
System.out.println("Enter the ID of the client you want to send the message to and a simple equation.");
System.out.println("Eg:2, 2 + 2 (with each element of the equation separated by a space…)");
while(true){
if(userInput.equals("Bye.")){
break;
}
if((userInput = stdIn.readLine()) != null){
out.println(userInput);
userInput = in.readLine();
System.out.println("echo: " + userInput);
System.out.println("Enter the ID of the client you want to send the message to and a simple equation.");
System.out.println("Eg:2, 2 + 2 (with each element of the equation separated by a space…)");
out.flush();
}
else if(in.ready()){
userInput = in.readLine();
System.out.println("echo: " + userInput);
System.out.println("Enter the ID of the client you want to send the message to and a simple equation.");
System.out.println("Eg:2, 2 + 2 (with each element of the equation separated by a space…)");
out.flush();
}
}
out.close();
in.close();
stdIn.close();
echoSocket.close();
}
}
In the server run method, at the end of the code where you are sending a message to one of the clients, you have
out.flush();
out.close();
in.close();
clientSocket.close();
}
}
catch (IOException e){
System.err.println("Problem with Communication Server");
System.exit(1);
}
This is closing the socket, and it why you are getting the exception. You may want to move this block to a place where you really do want to close the client's connection
You are getting a IOException because you're closing the stream you're trying to read from at line 140. I suggest you move all the steam closes out of while scope (line 142).
I have a client server architecture in Java in which I need to place a loop.
I've spent some time to think about where to put this loop, but anywhere I tried it did not get the result expected.
Here is my client.java :
public class Client {
private static Scanner scanner;
public static void main(String[] args) throws IOException {
scanner = new Scanner(System.in);
// set up server communication
Socket clientSocket = new Socket(InetAddress.getLocalHost(), 1234);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
System.out.println("Enter pin : ");
String password = scanner.next();
// send PIN to server
out.println(password);
out.flush();
// get response from server
String response = in.readLine();
System.out.println(response);
scanner.close();
in.close();
out.close();
clientSocket.close();
}
}
Here is my server.java :
public class Server {
private static ServerSocket server;
public static void main(String[] args) throws Exception {
server = new ServerSocket(1234);
Socket socket = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
// Listen for client requests:
String request = in.readLine();
while (request != null) {
// check PIN, send result
boolean pinCorrect = checkPin(request);
out.println(pinCorrect ? ":)" : ":(");
out.flush();
}
out.close();
in.close();
socket.close();
}
}
I need to repeat this process if the user does not enter exactly 4 digits, so I've been thinking of a do{}while(pinSize != 4) loop.
But when I place it in the Server I always have the wrong output ":)" or ":(" instead of just "Pin must be 4 digits", then I tried to put in the Client part, but this time I always had the possibility to enter only one pin so the loop did not work that much.
Actually this is some code I would put into my loop:
if (pinSize != 4) {
System.out.println("Pin must be 4 digits");
} else {
System.out.println("Checking...");
}
Any ideas ? Thanks.
Put the check in client side code. For more info read inline comments.
Fist use nextLine() in place of next() to read a whole line at a time.
Validation check for password along with its length check
Here is the modified client side code. Please incorporate the changes.
...
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
System.out.println("Enter pin : ");
String password = null;
// 4 digits pattern
Pattern p = Pattern.compile("\\d{4}");
while (true) {
password = scanner.nextLine();
int pinSize = password.length();
if (pinSize == 4) {
Matcher m = p.matcher(password);
if (m.find()) {
System.out.println("Checking " + password);
break;
} else {
System.out.println("Pin must be 4 digits");
}
} else {
System.out.println("Pin must be 4 digits");
}
}
// send PIN to server
out.println(password);
...
In this program, my server takes a command followed by 1 or 2 operands from the client and returns the result of the operation.
I am having trouble in scanning the line of client input and in performing the actual operation in the switch statement, if anyone could point me in the right direction I would appreciate it.
Here is the code:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
// Takes in a mathematical operation and the operands from a client and returns the result
// Valid operations are add, sub, multiply, power, divide, remainder, square
public class MathServer
{
public static void main(String [] args) throws IOException
{
ServerSocket yourSock = new ServerSocket(50000); //put server online
while(true)
{
System.out.println("Waiting to accept connection");
Socket clientSock = yourSock.accept(); //open server to connections
System.out.println("Connection accepted");
process(clientSock); //process accepted connection
System.out.println("Connection closed");
}
}
//BufferedReader(Reader r)
static void process(Socket sock) throws IOException
{
InputStream in = sock.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
OutputStream out = sock.getOutputStream();
PrintWriter pw = new PrintWriter(out, true);
String input = br.readLine(); //get user input from client
while(input != null && !input.equals("bye")) //check for input, if bye exit connection
{
int answer = operate(input); //perform desired operation on user input
pw.println(answer); //print out result
input = br.readLine(); //get next line of input
}
sock.close();
}
//Talk to the client
static int operate(String s)
{
System.out.println(s); //check if same as client input
Scanner myScanner = new Scanner(s);
String opType = myScanner.next(); //gets desired operation
System.out.println(opType); //checks for correct operation
switch (opType) {
case "add":
return (myScanner.nextInt() + myScanner.nextInt());
case "sub":
return (myScanner.nextInt() - myScanner.nextInt());
case "multiply":
return (myScanner.nextInt() * myScanner.nextInt());
case "power":
return (int) Math.pow(myScanner.nextInt(), myScanner.nextInt());
case "divide":
return myScanner.nextInt() / myScanner.nextInt();
case "remainder":
return myScanner.nextInt() % myScanner.nextInt();
case "square":
return (int) Math.pow(myScanner.nextInt(), 2);
default:
return (int) Math.pow(myScanner.nextInt(), 3);
}
}
}
As you're reading with BufferedReade.readLine() in your server, make sure you send a newline character from your client (common mistake). Also you may need to flush the OutputStream from your client. Because of the way that your Scanner reads in variables, you need to send in values on a single line from your client, e.g.
add 100 200
switch(opType) won't work for strings.
check with something like
if(opType.equals("add")){ //do Add }
else if(opType.equals("sub")){ //do subtraction }
etc.