Java DatagramSocket针对每个客户端请求的不同线程

时间:2015-12-15 11:27:15

标签: java java-threads

我正在开发Java项目,客户端通过DatagramSocket发送基本计算(例如5 + 6),服务器需要回复结果。目标是使用不同的线程计算每个不同的客户端请求。到目前为止,我有这段代码:

客户端:

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

    }
}

服务器:

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 {}
    }

    }

我有两个基本问题

1)如果我从客户端发送第二个请求(第一个执行正常),则会导致服务器输出Socket关闭错误消息。

2)正如您所见,在服务器端,我当前评论了sock.send(回复),因此我可以查看我在客户端添加的超时代码。问题是超时发生后(由于没有发送回复)代码从头开始,而不是我在TimeoutException catch()中指定的发送标签。

如果有人能帮助我解决这两个问题,我会非常感激

提前感谢您的时间!!!

2 个答案:

答案 0 :(得分:0)

在循环之前创建套接字。目前你正在让它被垃圾收集。

您在setSoTimeout()调用时发生套接字超时的声明不正确。它发生在receive()电话。

答案 1 :(得分:0)

修改后的代码似乎正在运行。让我知道你对此的看法

客户端:

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

服务器:

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

    }

    }

在客户端,args [1]表示服务器的IP地址。如果您的服务器在Localhost上运行,则可以使用“127.0.0.1”。