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


问题内容

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

基本上,我想要的是将多个客户端连接到服务器,并让每个客户端都有自己的线程。唯一的问题是,我不知道如何检查客户端是否尝试连接到服务器并为其生成新线程。

boolean listening = true;

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

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

在这种情况下,服务器将生成新线程,直到内存用完为止。这是ServerThread的代码(我想这里需要一种机制,该机制可以停止ServerThread的创建,直到客户端尝试连接为止。

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

所以Java编程之父请帮忙。


问题答案:

此设计在一定程度上取决于每个完整的UDP“对话”是否仅需要单个请求和立即响应,是单个请求还是带有重传的响应,或者是否需要为每个客户。

我编写的RADIUS服务器具有单个请求+重传模型,并为每个传入数据包生成了一个线程。

DatagramPacket接收到每个消息后,将其传递到新线程,然后该线程负责发送回响应。这是因为生成每个响应所涉及的计算和数据库访问可能会花费相对较长的时间,并且生成线程比使用某种其他机制来处理仍在处理旧数据包的新数据包要容易得多。

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