如何在 Java 中实现基于线程的 UDP 服务器?

2022-01-22 00:00:00 multithreading udp java

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 thread. The only problem is, that I don't know how to check if a client is trying to connect to the server and spawn a new thread for it.

boolean listening = true;

System.out.println("Server started.");

while (listening)
    new ServerThread().start();

In this case the server will spawn new threads until it runs out of memory. Here's the code for the ServerThread ( I think I need here a mechanism that stalls the creation of the ServerThread until a client tries to connect.

public ServerThread(String name) throws IOException 
{
    super(name);
    socket = new DatagramSocket();
}

So fathers of Java programming please help.

解决方案

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

相关文章