Java Server Basic Calculator - java

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.

Related

Java TCP Socket While loop and counter to receive data X times

I'm a amateur programmer and writing Java TCP socket client program that receives Integer and String type messages from the server(plc). Currently it works fine and returns correct values if using basic try catch without any loops to keep the program running.
But... I've been trying to add while loop with counter of 5 receive times that ends the program after that but it returns on ONE read:
Int: 705 //correct value that it should receive every time
String: testi3 //correct value that it should receive every time
Int: 0 // prints also this duplicate value
String: // prints also this duplicate value
How I should use the while loop in this case so it returns the correct values 5 times and then ends the program correctly?
My program looks like this:
import java.io.*;
import java.net.Socket;
import java.util.Arrays;
public class GetData2 {
private static int counter =0;
private Socket clientSocket;
//private PrintWriter out;
private String host = "192.168.0.1";
private int port2 = 2000;
private DataInputStream inFromServer;
public void start() throws IOException{
System.out.println("Client started");
clientSocket = new Socket(host, port2);
}
public void run() throws IOException {
while (counter <= 5) {
inFromServer = new DataInputStream(clientSocket.getInputStream());
//BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
int length = 100; // read length of incoming message
byte[] messageFromServer = new byte[length];
for (int i = 0; i < messageFromServer.length; i++) {
messageFromServer[i] = (byte) inFromServer.read(); //read message from the server
}
System.out.println("\n");
//System.out.println(Arrays.toString(messageFromServer));
byte[] copyOfData = Arrays.copyOf(messageFromServer, messageFromServer.length); //copies byte array from messageFromServer[] to copyOfData[]
System.out.println("\n");
//Integer
short value = 0;
// reads bytes 0-1
value = (short) (copyOfData[0] * 256 + (short) copyOfData[1]); // moves received bytes
// shows the order of received byes
System.out.println("Int: " + value); // return bytes as an Integer
//String
System.out.print("String: ");
for (int i = 4; i < copyOfData.length && i < 10; i++) { // reads bytes 4-10 from array
System.out.printf("%c", copyOfData[i]); // returns String testi2 from pythondemo 2 plc application
}
counter++;
System.out.println(counter);
}
}
public void stop() throws IOException{
//out.close();
System.out.println("Application stopped");
clientSocket.close();
inFromServer.close();
}
public static void main(String[] args) throws IOException {
GetData2 getData2 =new GetData2();
getData2.start();
getData2.run();
if(counter == 5){
getData2.stop();
}
}
}
EDIT:
Seems like if i change the received byte array length from [100] to [10], the program executes and prints this;
Client started
Int: 705
String: testi3
counter: 1
Int: 0
String:
counter: 2
Int: 0
String:
counter: 3
Int: 0
String:
counter: 4
Int: 0
String:
counter: 5
Application stopped
EDIT #2
So, I made server program that runs in localhost and sends byte[100] and it works correctly. Seems like problem is most likely in my PLC program, not in Java.
Server Class:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class GetData2_Server {
public static void main(String[] args) throws IOException {
System.out.println("server started");
Scanner scan = new Scanner(System.in);
ServerSocket server = new ServerSocket(8080);
Socket socket = server.accept();
System.out.println("server accepted");
System.out.println("1 == out n flush, 0 == close program");
int value = scan.nextInt();
byte[] bytesOut = new byte[100];
bytesOut[0]=0;
bytesOut[1]=3;
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
while (value == 1)
{
out.write(bytesOut);
out.flush();
value = scan.nextInt();
if(value == 0){
out.close();
socket.close();
}
}
}
}
in your while loop, you loop from 0 to 5, which means 6 times.
you may want to change this:
while (counter <= 5)
to this, so that it loops only 5 times:
while (counter < 5)
You are not taking into account that the device sending the data (I'll refer to it as "server" for short) may close the stream on its end. When this happens, inFromServer.read() will return -1. You're not checking for this value, so you will end up filling the messageFromServer array with -1 values.
If you know that the messages are supposed to be 100 bytes, you can read a message with a single DataInputStream method call, without a for loop. Replace your
for (int i = 0; i < messageFromServer.length; i++) with:
byte[] messageFromServer = new byte[length];
inFromServer.readFully(messageFromServer);
If the server stream is closed before the full message is read, this method will throw an exception (EOFException).

Java Math Server - Client side issues

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

Why multicasting isn't working?

My program doesn't work properly. The problem is that second client can't see messages from the first. I think problem is in while loop. Just not reading from IP adress. Can you help me?
Thank you in advance.
package multicastchat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class MulticastChat {
int chatRoom = 0;
int port = 0;
String ipAdress = "";
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public MulticastChat(){
}
public void choosingChatRoom() throws IOException{
while (!(chatRoom > 0 && chatRoom < 5)) {
System.out.println(
"We have four chat rooms, choose one of them (1, 2, 3, 4)");
chatRoom = Integer.valueOf(br.readLine());
switch (chatRoom) {
case 1:
port = 4441;
ipAdress = "230.0.0.1";
break;
case 2:
port = 4442;
ipAdress = "230.0.0.2";
break;
case 3:
port = 4443;
ipAdress = "230.0.0.3";
break;
case 4:
port = 4444;
ipAdress = "230.0.0.4";
break;
default:
System.out.println("Sorry, but we haven't this room, try another room");
this.choosingChatRoom();
break;
}
System.out.println("Welcome to room " + chatRoom);
}
}
public static void main(String[] args) throws IOException {
MulticastChat mc = new MulticastChat();
mc.choosingChatRoom();
MulticastSocket socket = new MulticastSocket(mc.port);
InetAddress address = InetAddress.getByName(mc.ipAdress);
socket.joinGroup(address);
DatagramPacket outMessage;
DatagramPacket inMessage;
String userInput;
while (true) {
//Receiving message
inMessage = new DatagramPacket(new byte[4096], 4096);
inMessage.setLength(inMessage.getData().length);
socket.receive(inMessage);
String received = new String(
inMessage.getData(), 0, inMessage.getLength());
System.out.println(received);
//Sending message
if ((userInput = mc.br.readLine()) != null) {
if (userInput.equals("quit")) {
System.out.println("Bye, see you later ^_^");
socket.leaveGroup(address);
socket.close();
System.exit(0);
} else {
byte[] buff = userInput.getBytes();
outMessage =
new DatagramPacket(buff, buff.length, address, mc.port);
socket.send(outMessage);
}
}
}
}
}
Assuming you are using the same program at both ends of the chat nothing will happen. Each instance starts up by reading from the socket, before anything's been written, so it will block forever.
No instance ever gets to where it can write to the socket.
Note that socket programming usually requires several threads as things are happening asynchronously on at least two "channels" (user interaction and socket I/O). A full explanation of how to write networking code is far beyond what StackOverflow is designed for.

HashMap InputStream / Scanner Server Problems

I'm making a client/server program for a computer science class.
The idea is that we have a server program that takes a list of console commands, performs them, and returns a response via Input / Output streams. Because of the formatting of the commands, I have to check for whitespaces and digits and split the strings accordingly (which I've done). The problem appears to be in the retrieval of the command from the InputStream.
Commands that should be accepted:
put [string] [int]
- this should store a string (key) and int (value) in the HashMap
get [string]
- this should return the int associated with this string
keyset
- return all keys
values
- return all values
mappings
- return all mappings
bye
- quit the client
help
- doesn't do anything yet, but will list all commands and their syntax
The professor gave us much of the code for the server, but I think there may be errors in it because I keep getting exceptions on the Scanner. See server code below:
package mapserver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class MapServer
{
public static void main(String[] args) throws IOException
{
ServerSocket serverSocket = new ServerSocket(50000);
while (true)
{
Socket activeSock = serverSocket.accept();
Thread th = new Thread(new MapServerThread(activeSock));
th.start();
}
}
}
class MapServerThread implements Runnable
{
private Map<String, Integer> map = new HashMap<>();
private Socket sock;
public MapServerThread(Socket s)
{
sock = s;
List<String> strs = Arrays.asList("aaa a", "b", "a");
for (String str : strs)
{
map.put(str, str.length());
}
}
#Override
public void run()
{
try
{
InputStream in = sock.getInputStream();
OutputStream out = sock.getOutputStream();
BufferedReader reader =
new BufferedReader(new InputStreamReader(in));
PrintWriter writer = new PrintWriter(out, true);
// welcome message
writer.println("Welcome to the map service.");
String inputLine = null;
while ((inputLine = reader.readLine()) != null)
{
Scanner sc = new Scanner(inputLine);
String fullLine =
sc.nextLine().toLowerCase().trim().replaceAll("\\s+", " ");
writer.println(fullLine);
int cmdLoc = 0;
for (int k = 0; k <fullLine.length(); k++)
{
if (fullLine.charAt(k)==' ');
{
cmdLoc = k;
}
}
String cmd;
if (cmdLoc == 0)
{
cmd = fullLine;
writer.println(cmd);
}
else
{
cmd = fullLine.substring(0, cmdLoc+1);
writer.println(cmd);
}
int startloc = cmd.length() + 1;
switch(cmd)
{
case "put":
int intlocation = startloc;
for (int k = 0; k < fullLine.length(); k++)
{
if (Character.isDigit(fullLine.charAt(k)))
{
intlocation = k;
}
}
// if the int is located at the beginning, the format
// is wrong. Let the user know
if (intlocation == startloc)
{
writer.println("Invalid entry. Correct format "
+ "is \"put <string> <integer>\"");
}
// Split the user's entry for putting
else
{
String stringToPut =
fullLine.substring(startloc, intlocation+1);
int intToPut =
Integer.parseInt(fullLine.substring(intlocation));
map.put(stringToPut, intToPut);
writer.println("Ok!");
}
continue;
case "get":
int returnvalue =
map.get(fullLine.substring(startloc));
writer.println(returnvalue);
continue;
case "keyset":
String result = map.keySet().toString();
writer.println(result);
continue;
case "values" :
String result1 = map.values().toString();
writer.println(result1);
continue;
case "mappings" :
writer.println(map.size());
map.forEach(
(k, v) ->
{ writer.println( k + " " + v);}
);
continue;
case "bye" :
writer.println("See you later.");
sock.shutdownOutput();
sock.close();
return;
case "help" :
continue;
default :
writer.println("Not a recognized command");
}
}
} catch (IOException ex)
{
throw new RuntimeException(ex);
}
}
}
I'm almost 100% sure the problem is in the server program, as I've been testing it with Telnet. I've tried using the BufferedReader directly instead of the scanner, but the server appears to be getting blank strings. Does anyone have any ideas? I've been fiddling with it for a couple of hours now and I just can't figure it out.
The Problem in a nutshell:
After I login, the server throws:
Exception in thread "Thread-0" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at mapserver.MapServerThread.run(MapServer.java:67)
at java.lang.Thread.run(Thread.java:745)
and I can't figure out why. If i don't use the scanner, for some reason the server is receiving blank input, regardless of what i type.
Here's what the correct interaction should look like:
Welcome to the MapService Client
Enter the IP address of the server: localhost
Please wait while I connect you...
Welcome to the map service.
Map service>mappings
3
a 1
b 1
aaa a 5
Map service>put North Central College 2014
Ok.
Map service>keyset
[a, b, aaa a, North Central College]
Map service>get North Central College
2014
Map service>help
7
help
get key
put key value
values
keyset
mappings
bye
Map service>values
[1, 1, 5, 2014]
Map service>bye
See you later.
Your code is broken, because it's trying to parse the same line twice:
String inputLine = null;
while ((inputLine = reader.readLine()) != null) //#1
//...
String fullLine =sc.nextLine().toLowerCase().trim().replaceAll("\\s+", " ");//#2
You can fix that particular piece with:
String fullLine =inputLine.toLowerCase().trim().replaceAll("\\s+", " ");
If you receive a blank inputLine for whatever reason, you can skip it with:
if(inputLine.trim().size()==0){
continue;//invokes the next loop iteration
}
EDIT:
I rewrote the class and tried to split up the parts to make it easier to grasp. Please give a feedback even though you marked it resolved:
class MapServerThread implements Runnable {
private enum Commands {
PUT("(put)\\s(\\S+)\\s(\\d)"),
//add all your commands here and give an approriate regular expression
UNKNOWN(".+");
private final String pattern;
Commands(String regexPattern) {
pattern = regexPattern;
}
private static Commands parseCommand(String s) {
Commands result = UNKNOWN;
s = s.toLowerCase(Locale.getDefault());
for (Commands command : values()) {
if (command != UNKNOWN && command.pattern.matches(s)) {
result = command;
break;
}
}
return result;
}
}
private Map<String, Integer> map = new HashMap<>();
private Socket sock;
public MapServerThread(Socket s) {
sock = s;
List<String> strs = Arrays.asList("aaa a", "b", "a");
for (String str : strs) {
map.put(str, str.length());
}
}
#Override
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
PrintWriter writer = new PrintWriter(sock.getOutputStream(), true);
writer.println("Welcome to the map service.");
String inputLine = null;
while ((inputLine = reader.readLine().trim()) != null) {
Commands command = Commands.parseCommand(inputLine);
writer.println(command.name());
execute(command, inputLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void execute(Commands command, String inputLine) {
switch (command) {
case PUT:
String[] args = inputLine.split(" ");
map.put(args[1], Integer.parseInt(args[2]));
break;
//handle the other commands accordingly
default:
// notify about an error
break;
//
// get [string] - this should return the int associated with this string
//
// keyset - return all keys
//
// values - return all values
//
// mappings - return all mappings
//
// bye - quit the client
//
// help - doesn't do anything yet, but will list all commands and their
// syntax
}
}
}

Where to place my loop for better results in Client-Server architecture in Java?

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);
...

Categories