我正在尝试构建一个服务器,该服务器可以通过UDP在同一端口号上同时处理多个请求。下面是相同的Java代码。
Runnable task = () ->
{
DatagramSocket aSocket=null;
while(true)
{
try
{
aSocket= new DatagramSocket(2222);
byte[] buffer=new byte[1000];
DatagramPacket Reply=new DatagramPacket(buffer,buffer.length);
aSocket.receive(Reply);
String rec=new String(Reply.getData());
System.out.println("rec "+rec);
String[] splited = rec.split("\\s+");
System.out.println("Operation "+splited[0]);
if(splited[0].equalsIgnoreCase("Enroll"))
{
String ret=cs.enrollCourse(splited[1],splited[2],splited[3]);
byte[] temp=new byte[1000];
temp=ret.getBytes();
DatagramPacket se=new DatagramPacket(temp,temp.length,Reply.getAddress(),Reply.getPort());
aSocket.send(se);
}
if(splited[0].equalsIgnoreCase("Drop"))
{
String ret=cs.drop_external(splited[1],splited[2]);
byte[] temp=new byte[1000];
temp=ret.getBytes();
DatagramPacket se=new DatagramPacket(temp,temp.length,Reply.getAddress(),Reply.getPort());
aSocket.send(se);
aSocket.close();
}
if(splited[0].equalsIgnoreCase("list"))
{
String ret=cs.listCourseAvailability(splited[1],splited[2]);
byte[] temp=new byte[1000];
temp=ret.getBytes();
DatagramPacket se=new DatagramPacket(temp,temp.length,Reply.getAddress(),Reply.getPort());
aSocket.send(se);
}
if(splited[0].equalsIgnoreCase("Remove"))
{
String ret=cs.removeCourse(splited[1],splited[2]);
byte[] temp=new byte[1000];
temp=ret.getBytes();
DatagramPacket se=new DatagramPacket(temp,temp.length,Reply.getAddress(),Reply.getPort());
aSocket.send(se);
}
}catch(Exception e)
{
System.out.println(e.getMessage());
}
finally
{
if (aSocket != null)
{
aSocket.close();
}
}
}
};
Thread t=new Thread(task);
t.start();
两个请求同时到达时,上述代码未接收到其中一个。
实施是否正确?还有其他方法可以使用UDP实现相同功能吗?
答案 0 :(得分:0)
在处理每个传入数据包并发送答复之后,您将关闭DatagramSocket
,并打开一个新的数据包。这(可能)将导致OS丢弃已接收但尚未处理的所有数据包。
解决方案:不要那样做。使用单个DatagramSocket
,仅在线程即将退出时将其关闭。
实际上,线程在这里并没有真正的用途……虽然这不是造成问题的原因。