-1

I'm working on a project in Java where clients send via DatagramSocket a basic calculation (eg 5+6) and the Server needs to reply with the result. The goal is to have a different thread calculating each different client request. So far I have this code:

Client:

import java.net.*;
import java.io.*; 
public class UDPClient {
    public static void main (String args[]){
        DatagramSocket aSocket = null;
        int input=-1;
        String operation=null;
        while(input!=0){
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("Select an option");
            System.out.println("1. Do a basic calculation");
            System.out.println("0. Exit ");
            try{
                input = Integer.parseInt(br.readLine());
                if(input>1 | input<0)throw new Exception("Error");
            }
              catch(Exception e){
                    System.out.println("Wrong selection...Try again \n");
                }
            if(input==1)
            {
                    System.out.println("Give operator symbol (+,-,*,/) ");
                    try{
                        String operator = br.readLine();
                        if(!(operator.matches("[*]|[+]|[/]|[-]")))throw new Exception("Error");
                        System.out.println("Give first number");
                        int first = Integer.parseInt(br.readLine());
                        System.out.println("Give second number");
                        int second = Integer.parseInt(br.readLine());
                        operation =  first+":"+operator+":"+second;
        send:
            try{
                aSocket = new DatagramSocket();
                byte [] m = operation.getBytes();
                InetAddress aHost = InetAddress.getByName(args[1]);
                int serverPort = 6789;
                DatagramPacket request = new DatagramPacket(m, m.length, aHost, serverPort);
                aSocket.send(request);
                aSocket.setSoTimeout(10000); // SocketTimeout happens here
                byte[]buffer = new byte[1000];
                DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
                aSocket.receive(reply);
                System.out.println("Reply:" + new String(reply.getData()));

            }
            catch (SocketTimeoutException e) {
                System.out.println("Server reply timeout");
                break send;  //If Timeout happens, send request again
            }
            catch(SocketException e){
                System.out.println("Socket: " + e.getMessage());
            }
            catch(IOException e){
                    System.out.println("IO: " + e.getMessage());
            }
            finally {if (aSocket!=null) aSocket.close();}
            }
            catch(Exception e){
                System.out.println("Wrong input...Try again \n"); 
            }

        }//End of if
    }//end of while

    }
}

Server:

import java.net.*;
import java.nio.charset.Charset;
import java.io.*; 
public class UDPServer {
    static DatagramSocket aSocket = null;
    public static void main (String args[]){

        int i=0;
        try{
            aSocket = new DatagramSocket(6789);
            byte[] buffer = new byte[1000];
            while(true){
                DatagramPacket request = new DatagramPacket(buffer, buffer.length);
                aSocket.receive(request);   
                new ClientThread(aSocket,request);
            }
        }
        catch(SocketException e){
            System.out.println("Socket: " + e.getMessage());
        }
        catch(IOException e){
                System.out.println("IO: " + e.getMessage());
        }
    }
}

class ClientThread extends Thread{

    DatagramSocket sock;
    DatagramPacket request;
    public ClientThread(DatagramSocket sock, DatagramPacket request){
        this.sock=sock;
        this.request=request;
        this.start();

    }

    public void run() {

        try{
            String input = new String(request.getData());
            String[] in = input.split("[:]");
            double temp=0;
            if (in[1].matches("[+]")) temp = Double.valueOf(in[0])+Double.valueOf(in[2]);
            if (in[1].matches("[-]")) temp = Double.valueOf(in[0])-Double.valueOf(in[2]);
            if (in[1].matches("[*]")) temp = Double.valueOf(in[0])*Double.valueOf(in[2]);
            if (in[1].matches("[/]")) temp = Double.valueOf(in[0])/Double.valueOf(in[2]);
            String result ="Result: "+temp + " from Thread: "+ Thread.currentThread().getName() + "\n";
            DatagramPacket reply =  new DatagramPacket(result.getBytes(Charset.forName("UTF-8")),
                    result.length(),request.getAddress(),request.getPort());
            //sock.send(reply);
            System.out.println(result);

        }
        /*
        catch(SocketException e){
            System.out.println("Socket: " + e.getMessage());
        }
        catch(IOException e){
                System.out.println("IO: " + e.getMessage());
        }
        */
        finally {}
    }

    }

I have two basic problems

1) If I send a second request from Client (first one executes fine) it causes the Server to output a Socket closed error message.

2) As you can see In Server side I've currently commented sock.send(reply) so I can check the timeout code I've added in the Client's side. The problem is that after timeout happens (since no reply is ever send) code starts from the beginning and not the send label I specified inside the TimeoutException catch().

If anyone can help me with any of those two problems, I would be very gratefull

Thanks in advance for your time!!!

V. Georga
  • 9
  • 4

2 Answers2

0

Create the socket ahead of the loop. At present you're letting it be garbage-collected.

Your statement that the socket timeout happens at the setSoTimeout() call is incorrect. It happens at the receive() call.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Thank you for your time but I m not able to comprehend your correction. Could you be more specific please? – V. Georga Dec 15 '15 at 13:52
0

Revised code seems to be working. Let me know your opinion on this

Client:

import java.net.*;
import java.io.*; 
public class UDPClient {
    public static void main (String args[]){
        DatagramSocket aSocket = null;
        int input=-1; //User Input from menu
        String operation=null; //keeps the calculation operation in String form
        int resends=0; //NACK counter
        while(input!=0){
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("Select an option");
            System.out.println("1. Do a basic calculation");
            System.out.println("0. Exit ");
            try{
                input = Integer.parseInt(br.readLine());
                if(input>1 | input<0)throw new Exception("Error");
            }
              catch(Exception e){
                    System.out.println("Wrong selection...Try again \n");
                }
            if(input==1)
            {
                    System.out.println("Give operator symbol (+,-,*,/) ");
                    try{
                        String operator = br.readLine();
                        if(!(operator.matches("[*]|[+]|[/]|[-]")))throw new Exception("Error");
                        System.out.println("Give first number");
                        int first = Integer.parseInt(br.readLine());
                        System.out.println("Give second number");
                        int second = Integer.parseInt(br.readLine());
                        operation =  first+":"+operator+":"+second;
                    }
                    catch(Exception e){
                        System.out.println("Wrong input...Try again \n"); 
                        System.out.println(e.getMessage());
                    }
           while(true){
                try{
                    if(resends==3){ // At 3 resends break loop
                        resends=0;
                        break;              
                    }
                    aSocket = new DatagramSocket();
                    byte [] m = operation.getBytes();
                    InetAddress aHost = InetAddress.getByName(args[1]);
                    int serverPort = 6789;
                    DatagramPacket request = new DatagramPacket(m, m.length, aHost, serverPort);
                    aSocket.send(request);
                    resends++;//counting times we send this message
                    aSocket.setSoTimeout(30000); // Setting timeout for socket (30 sec)
                    byte[]buffer = new byte[1000];
                    DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
                    aSocket.receive(reply);
                    System.out.println("Reply:" + new String(reply.getData()));
                    if(reply!=null)break; // If you get a reply, break loop

                }
                catch (SocketTimeoutException e) {
                    System.out.println("Server reply timeout");         

                }
                catch(SocketException e){
                    System.out.println("Socket: " + e.getMessage());
                }
                catch(IOException e){
                        System.out.println("IO: " + e.getMessage());
                }
                finally {if (aSocket!=null) aSocket.close();}              
           }// end of send while loop

        }//End of if
            else if (input==0)
                System.out.println("Exiting UDP Client.....");

     }//end of while
  }//end of main

}//end of Class

Server:

import java.net.*;
import java.nio.charset.Charset;
import java.io.*; 
public class UDPServer {

    public static void main (String args[]){
        DatagramSocket aSocket = null;
        try{
            aSocket = new DatagramSocket(6789);
            byte[] buffer = new byte[1000];
            while(true){
                DatagramPacket request = new DatagramPacket(buffer, buffer.length);
                aSocket.receive(request);   
                new ClientThread(aSocket,request);
            }
        }
        catch(SocketException e){
            System.out.println("Socket: " + e.getMessage());
        }
        catch(IOException e){
                System.out.println("IO: " + e.getMessage());
        }
        finally {if(aSocket!=null)aSocket.close();}
    }
}

class ClientThread extends Thread{

    DatagramSocket sock;
    DatagramPacket request;
    public ClientThread(DatagramSocket sock, DatagramPacket request){
        this.sock=sock;
        this.request=request;
        this.start();

    }

    public void run() {

        try{
            String input = new String(request.getData());
            String[] in = input.split("[:]");
            String result;
            double temp=0;
            if (in[1].matches("[+]")) temp = Double.valueOf(in[0])+Double.valueOf(in[2]);
            if (in[1].matches("[-]")) temp = Double.valueOf(in[0])-Double.valueOf(in[2]);
            if (in[1].matches("[*]")) temp = Double.valueOf(in[0])*Double.valueOf(in[2]);
            if (in[1].matches("[/]")) temp = Double.valueOf(in[0])/Double.valueOf(in[2]);
            result ="Result: "+temp + " from Thread: "+ Thread.currentThread().getName() + "\n";
            DatagramPacket reply =  new DatagramPacket(result.getBytes(Charset.forName("UTF-8")),
                    result.length(),request.getAddress(),request.getPort());
            sock.send(reply);   
            //System.out.println(result);
        }
        catch(SocketException e){
            System.out.println("Socket: " + e.getMessage());
        }
        catch(IOException e){
                System.out.println("IO: " + e.getMessage());
        }

    }

    }

In Client side, args[1] represents the Server's IP address. You can use "127.0.0.1" if your Server is running on Localhost.

V. Georga
  • 9
  • 4