Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在不使用while循环的情况下运行服务器?_Java_Multithreading_Datagram - Fatal编程技术网

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

Java 如何在不使用while循环的情况下运行服务器?,java,multithreading,datagram,Java,Multithreading,Datagram,我试图使用DatagramSocket和DatagramPacket类创建一个服务器程序,但是我当前的代码使用了一个丑陋的while循环,它在服务器运行时也冻结了我的程序,但是服务器运行正常,没有问题。无论如何,代码如下。我是否可以使用与while循环不同的东西,或者阻止while循环阻止程序中的任何其他代码执行 protected void run() { try { socket = new DatagramSocket(port); socket.s

我试图使用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
        }
    }
}
受保护的无效运行(){
试一试{
套接字=新的DatagramSocket(端口);
插座。路演(真实);
}捕获(例外e){
e、 printStackTrace();
stopServer();//停止服务器
返回;
}
当(isRunning()){//讨厌这个循环
试一试{
字节[]buf=新字节[256];
DatagramPacket数据包=新的DatagramPacket(buf,256);
套接字接收(数据包);
数据包;
字节[]serverBuf;
字节hb=0;
字节lb=packet.getData()[0];

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


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

我怀疑您是否能够摆脱该循环,因为从逻辑上讲,您希望您的服务器“服务”多个请求。每个请求都将在服务器循环的一次迭代中服务

现在,服务器通常只关心接收请求,并将它们发送到线程池进行处理

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

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

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

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


它是专门为此设计的,并提供了一个实现,对于您的应用程序来说,这可能是一个更好的设计选择。

?另外,请记住,您应该在循环中的关键位置检查Thread.currentThread().isInterrupted()。这允许管理此线程实例的任何人都可以使用它(主程序或其他)调用thread.interrupt()并实际关闭服务器。否则,我怀疑socket.receive()将是唯一可以被中断的部分。而且,每次从“receive()”获取套接字时方法,您可能应该将套接字发送到ExecutorService实例进行处理,否则您已经编写了一个单线程服务器(这可能是您的意图)。