如何在不使用while循环的情况下运行服务器?

时间:2012-07-15 13:08:07

标签: java multithreading datagram

我试图使用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
        }
    }
}

3 个答案:

答案 0 :(得分:8)

你应该把它放在一个新的线程中。接收数据包的过程涉及同步IO,因此它将始终阻止它运行的任何线程。

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

答案 1 :(得分:4)

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

现在,通常情况下,您的服务器只关心接收请求,并将它们分发给要处理的线程池。

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

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

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

答案 2 :(得分:0)

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

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