0

guys! i wrote simple server client (udp) application. Now i am trying to make server that accepts many clients. As, i understood, i need to create functions, that accepts and handle clients, but i am confused about apps structure. Can u check if i have right skeleton for my app? Mayb u can give me some hint or example. All advice appreciated! :)

class MultiServer {

    private DatagramSocket serversocket;

    public MultiServer() {
        try {
            this.serversocket = new DatagramSocket(6789);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void start() throws IOException {
        while(true) {
            DatagramSocket serversock = serversocket.accept();
            new Thread(new ClientHandler(serversock)).start();
        }
    }

    public static void main(String[] args) {
        Server1 server = new Server1();
        try {
            server.start();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

class ClientHandler implements Runnable {

        private final DatagramSocket clientsocket;

        ClientHandler(DatagramSocket sock) {
            this.clientsocket = sock;
        }

        @Override
        public void run() {
            //receive packet, send msg, get ip, get portnumber ?
        }

    }

}
chajka
  • 51
  • 2
  • 4
  • 13

2 Answers2

1

So you want your server to be able to operate with multiple requests at the same time? Good, it's how most web-servers work. You have to understand the basic concepts of multi-threading and concurrency.

A simple server can only handle ONE thing at a time. What happens if another request is received while the server is dealing with something else? Nothing, so the application isn't very efficient and not scalable at all.

If you haven't used multiple threads in your applications yet and don't know much about concurrency, it's a great time to have a go, read the Oracle Concurrency Lesson, or find a tutorial online, there are plenty.

Now, once (or if) you know how threading works make sure you break down your functions as much as possible and see what functions can happen at the same time. An example of a Web Server that i can think of is this:

  • A separate thread to listen on the port for requests. Once a request is received, place it in the 'request pool' and queue it to be processed
  • A separate thread (or multiple threads/thread pool) that process the request

Your structure looks like you have both receive and process in the same Runnable. Anyway, this is just an idea, you'll have to see what's more applicable to your application. Also, have a look at the Concurrency tools that newer Java versions provide, Java 6 and 7 provide a lot of tools you can use that are very effective (but also quite hard to understand and use in my opinion).

Good luck!

Slava
  • 48
  • 6
0

You are looking for a Threadpooled Server. The way you started is good. Now you simply implement a Java execution Service to Handle the requests. The threadpool has a fixed of thread. It does take your requests and put those in a queue and if a request is done it takes the next request. So you normaly dont lose any requests.

Here is a small example i made:

public class PoolServer implements Runnable {
    private static final int DEFAULT_PORT = 8080;
    private static final String CONFIG = "config.xml";
    protected ServerSocket serverSocket = null;
    protected boolean isStopped = false;
    protected Thread runningThread = null;
    protected ExecutorService threadPool = Executors.newFixedThreadPool(100);
    protected int serverPort;

    public PoolServer() {
        // getting the port from the XML
        this.serverPort = getPortFromXML();
    }

    public void run() {
        synchronized (this) {
            this.runningThread = Thread.currentThread();
        }
        openServerSocket();
        // accepting loop
        while (!isStopped()) {
            Socket clientSocket = null;
            try {
                // accept the client
                clientSocket = this.serverSocket.accept();
                clientSocket.setSoTimeout(2000);

            } catch (IOException e) {
                if (isStopped()) {
                    return;
                }
                throw new RuntimeException("Error accepting client connection",
                        e);
            }
            this.threadPool.execute(new ThreadHandler(clientSocket));
        }
        // loop end
        // server stopped shut down the ThreadPool
        this.threadPool.shutdown();
    }

    private synchronized boolean isStopped() {
        return this.isStopped;
    }

    public synchronized void stop() {
        this.isStopped = true;
        try {
            this.serverSocket.close();
        } catch (IOException e) {
            throw new RuntimeException("Error closing server", e);
        }
    }

    private void openServerSocket() {
        try {
            this.serverSocket = new ServerSocket(this.serverPort);
        } catch (IOException e) {
            throw new RuntimeException("Cannot open port " + this.serverPort, e);
        }
    }

At this point this.threadPool.execute(new ThreadHandler(clientSocket)); i do execute the request if a thread is free. Else it get into the queue of the Threadpool.

You can even change it from a Fixed to some other Threadpools! Just take a look at the Executors and take what you need. Executors
Hope this helps!

bemeyer
  • 6,154
  • 4
  • 36
  • 86