我试图使用DatagramSocket和DatagramPacket类创建一个服务器程序,但是我当前的代码使用了一个丑陋的while循环,它在服务器运行时也冻结了我的程序,但服务器运行正常,没有任何问题。无论如何,代码如下。无论如何我可以使用不同于while循环的东西或阻止while循环阻止程序中的任何其他代码执行吗?
protected void run() {
try {
socket = new DatagramSocket(port);
socket.setBroadcast(true);
} catch (Exception e) {
e.printStackTrace();
stopServer(); //stop the server
return;
}
while(isRunning()){ //hate this loop
try {
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, 256);
socket.receive(packet);
DatagramPacket serverPacket;
byte[] serverBuf;
byte hb = 0;
byte lb = packet.getData()[0];
int e = ((int)hb<<8)|((int)lb&0xFF); //translate byte to int
switch(e) {
case 2:
//do something
break;
case 5:
//do something
break;
case 7:
//do something
break;
default:
//default stuff
break;
}
} catch (Exception e) {
System.out.println("Fatal Server Error:");
e.printStackTrace();
stopServer(); //stop the server
return; //stop the method
}
}
}
答案 0 :(得分:8)
你应该把它放在一个新的线程中。接收数据包的过程涉及同步IO,因此它将始终阻止它运行的任何线程。
为了澄清,不是while循环本身使程序的其余部分等待。这是socket.receive()调用。
答案 1 :(得分:4)
我怀疑你可以摆脱循环,因为从逻辑上讲,你打算让你的服务器“服务”多个请求。每个请求都将在服务器循环的一次迭代中提供。
现在,通常情况下,您的服务器只关心接收请求,并将它们分发给要处理的线程池。
因此,您不会让服务器线程担心给定请求的处理。基本上是因为如果您的服务器忙于处理请求,那么在此期间它无法访问到达其端口的任何其他服务器。
建议是,接收数据包,并立即将收到的数据传递给另一个线程进行处理。
显然,这并不意味着删除有问题的循环,正如我所提到的,除非您打算只提供来自客户的一个请求(这是一个相当不可能的场景),否则这是不可能的。这样可以保证请求可以独立进行,并且它们的处理不会延迟到达到达服务器端口的其他请求。
答案 2 :(得分:0)
我建议使用Apache Mina来管理您的流量和网络通信。
它专为此而设计,并提供Reactor design pattern的实现,这可能是您的应用程序的更好的设计选择。