How can I implement a threaded UDP based server in Java?

后端 未结 4 1667
无人共我
无人共我 2020-12-13 15:54

How can I implement a threaded UDP based server in Java ?

Basically what I want, is to connect multiple clients to the server, and let each client have his own threa

相关标签:
4条回答
  • 2020-12-13 16:15

    Since UDP is a connectionless protocol, why do you need to spawn a new thread for each connection? When you receive a UDP packet maybe you should spawn a new thread to take care of dealing with the message received.

    UDP connections are not like TCP connections. They do not remain active and such is the design of UDP.

    The handlePacket() method of this next code block can do whatever it wants with the data received. And many clients can send multiple packets to the same UDP listener. Maybe it will help you.

    public void run() {
            DatagramSocket wSocket = null;
            DatagramPacket wPacket = null;
            byte[] wBuffer = null;
    
            try {
                wSocket = new DatagramSocket( listenPort );
                wBuffer = new byte[ 2048 ];
                wPacket = new DatagramPacket( wBuffer, wBuffer.length );
            } catch ( SocketException e ) {
                log.fatal( "Could not open the socket: \n" + e.getMessage() );
                System.exit( 1 );
            }
    
            while ( isRunning ) {
                try {
                    wSocket.receive( wPacket );
                    handlePacket( wPacket, wBuffer );
                } catch ( Exception e ) {
                    log.error( e.getMessage() );
                }
            }
        }
    
    0 讨论(0)
  • 2020-12-13 16:29

    Have you looked at the Apache Mina project? I believe even one of its examples takes you through how to setup an UDP-based server with it. If this for a real product, I would not recommend trying to come up with your own implementation from scratch. You will want to use a library to accomplish this so you are not using one thread per connection, rather a thread pool.

    0 讨论(0)
  • 2020-12-13 16:30

    I don't really see the need.

    Its a school thing right?

    If you need to keep track of the clients, you should have a local representation of each client (a Client object on your server). It can take care of whatever client-specific things you need to do.

    In that case You need to be able to find out from which client the message was sent from. (using information from the message.) You can keep the clients in a map.

    The most effective way is probably to do all handling in the main thread, unless whatever that needs to be done can "block" waiting for external events (or if some things that's supposed to happen might take a long time and some a very short.)

    public class Client {
    
        public void handleMessage(Message m) {
        // do stuff here.
        }
    
    }
    

    The client object can perhaps start a new thread in handleMessage() if neccesary.

    You shouldn't start multiple server threads.

    The server thread can do:

    while(running) {
      socket.receive(DatagramPacket p);
      client = figureOutClient(p);
      client.handleMessage(p);
    }
    

    If there are no client-specific things to care about, just read the messages and handle them as they arrive, in one thread.

    0 讨论(0)
  • 2020-12-13 16:33

    The design for this to a certain extent depends on whether each complete UDP "dialog" just requires a single request and immediate response, whether it's a single request or response with retransmissions, or whether there'll be a need to process lots of packets for each client.

    The RADIUS server I wrote had the single request + retransmit model and spawned a thread for each incoming packet.

    As each DatagramPacket was received it was passed to a new thread, and then that thread was responsible for sending back the response. This was because the computation and database accesses involved in generating each response could take a relatively long time and it's easier to spawn a thread than to have some other mechanism to handle new packets that arrive whilst old packets are still being processed.

    public class Server implements Runnable {
        public void run() {
            while (true) {
                DatagramPacket packet = socket.receive();
                new Thread(new Responder(socket, packet)).start();
            }
        }
    }
    
    public class Responder implements Runnable {
    
        Socket socket = null;
        DatagramPacket packet = null;
    
        public Responder(Socket socket, DatagramPacket packet) {
            this.socket = socket;
            this.packet = packet;
        }
    
        public void run() {
            byte[] data = makeResponse(); // code not shown
            DatagramPacket response = new DatagramPacket(data, data.length,
                packet.getAddress(), packet.getPort());
            socket.send(response);
        }
    }
    
    0 讨论(0)
提交回复
热议问题