3

I'm trying to make a server program using the DatagramSocket and DatagramPacket classes, but my current code uses an ugly while loop which also freezes my program while the server runs, but the server runs fine with no problems. Anyway the code is below. Is there anyway I can use something different than a while loop or prevent the while loop from preventing any other code in the program to execute?

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
        }
    }
}
ioreskovic
  • 5,531
  • 5
  • 39
  • 70
jocopa3
  • 796
  • 1
  • 10
  • 29

3 Answers3

8

You should put this in a new thread. The process of receiving a packet involves synchronous IO, so it will always block whichever thread it's running in.

To clarify, it's not the while loop itself that makes the rest of the program wait. It's the socket.receive() call.

QuantumBadger
  • 196
  • 1
  • 4
  • Also, keep in mind you should be putting a check for Thread.currentThread().isInterrupted() at strategic places in your loop. This allows whoever is managing this thread instance (main program or something else) to call thread.interrupt() and actually shut your server down. Otherwise, I suspect that the socket.receive() will the only part that can be interrupted. Also, each time you get a socket from the "receive()" method, you should probably send the socket off to a ExecutorService instance for processing, otherwise you've coded a single threaded server (which may be your intent though). – Matt Jul 15 '12 at 19:09
4

I doubt that you can get rid of the loop because you, logically, intend that your server "serves" multiple requests. Every request will be served in one iteration from the server loop.

Now, it is customary that your server will only care about receiving the requests and will dispatch them to a thread pool to be processed.

As such, you do not make your server thread worry about the processing of a given request. Basically because if your server is busy processing the request it cannot attend any other ones arriving to its port during that time.

The recommendation would be, receive the packets, and immediatelly pass the received data to another thread for processing.

This, evidently, will not imply the removal of the loop in question, which as I mentioned, is not possible unless you intend to serve only one request from your clients (a rather unlikely scenario). This would guarantee that the requests can be proccessed independently and their processing will not delay attending other requests arriving at the server port.

Edwin Dalorzo
  • 76,803
  • 25
  • 144
  • 205
  • Are the most common web servers in different languages all relying on a (while) loop for receiving requests? Are there any notable exceptions? – ZenVentzi Oct 06 '22 at 14:10
0

I would recommend using Apache Mina to manage your flow and network communication.

It was designed for this particularly and provides an implementation of the Reactor design pattern which might be a better design choice for your application.

RonK
  • 9,472
  • 8
  • 51
  • 87