如何在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); } }
由于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() ); } } }