3

我正在尝试使用 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
        }
    }
}
4

3 回答 3

8

你应该把它放在一个新线程中。接收数据包的过程涉及同步 IO,因此它总是会阻塞它正在运行的任何线程。

澄清一下,让程序的其余部分等待的不是 while 循环本身。这是 socket.receive() 调用。

于 2012-07-15T13:17:11.137 回答
4

我怀疑您是否可以摆脱循环,因为从逻辑上讲,您打算让您的服务器“服务”多个请求。每个请求都将在服务器循环的一次迭代中得到服务。

现在,您的服务器通常只关心接收请求并将它们分派到线程池进行处理。

因此,您不必让服务器线程担心给定请求的处理。基本上是因为如果您的服务器正忙于处理请求,那么在此期间它无法处理任何其他到达其端口的请求。

建议是,接收数据包,并立即将接收到的数据传递给另一个线程进行处理。

显然,这并不意味着删除有问题的循环,正如我所提到的,除非您打算只处理来自客户的一个请求(一种不太可能的情况),否则这是不可能的。这将保证可以独立处理请求,并且它们的处理不会延迟处理到达服务器端口的其他请求。

于 2012-07-15T13:24:44.447 回答
0

我建议使用Apache Mina来管理您的流量和网络通信。

它专门为此而设计,并提供了Reactor设计模式的实现,这可能是您的应用程序更好的设计选择。

于 2012-07-15T13:33:09.757 回答