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

2022-09-03 12:38:29

如何在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编程之父请帮忙。


答案 1

在某种程度上,这方面的设计取决于每个完整的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);
    }
}

答案 2

既然UDP是一种无连接协议,为什么需要为每个连接生成一个新线程?当您收到UDP数据包时,也许您应该生成一个新线程来处理收到的消息。

UDP 连接与 TCP 连接不同。它们不会保持活动状态,这就是UDP的设计。

下一个代码块的 handlePacket() 方法可以对接收到的数据执行任何操作。许多客户端可以将多个数据包发送到同一个 UDP 侦听器。也许它会帮助你。

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