1

I am running a server and spawning multiple threads to allow for multiple sockets. Obviously, I want to be able to close all sockets on command. I wrote a start and a stop function for my server and it works near instantly unless I run it on Windows.

Start/Stop

public void startServer(int port, int maxThreads, int timeout) throws IOException {

    fileServer = new ServerSocket();
    fileServer.setPerformancePreferences(1, 0, 1);
    fileServer.bind(new InetSocketAddress(port));

    for (int threads = 0; threads < maxThreads; threads++) {
        sockets.add(new Thread(new ServerInit(fileServer, timeout)));
        System.out.println("Socket " + threads + " initialized...");
    }

    for (int socket = 0; socket < sockets.size(); socket++) {
        (sockets.get(socket)).start();
        System.out.println("Socket " + socket + " started!");
    }
}

public void stopServer() {
    if (fileServer.isBound()) {
        for (int thread = 0; thread < sockets.size(); thread++) {
            sockets.get(thread).interrupt();
        }
        for (int thread = 0; thread < sockets.size(); thread++) {
            try {
                sockets.get(thread).join();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

ServerInit

class ServerInit implements Runnable {
    private ServerSocket server;
    private int timeout;

    public void run() {
        while (!Thread.interrupted()) {
            try {
                server.setSoTimeout(1000);
                Socket client = server.accept();
                client.setSoTimeout(timeout);
                processRequest(receiveRequest(client), client);
                client.close();
            } catch (SocketTimeoutException ste) {
            } catch (IOException io) {
                io.printStackTrace();
            }
        }
        System.out.println("Socket closed");
     }
}

The issue is that each thread individually takes one second to stop because of the blocking timeout, however, this only occurs on Windows. Why is Windows behaving so differently and how should I go about resolving this issue?

EDIT

Each socket has a one second timeout. I realize that by doing this it causes each socket to take one second to timeout and therefore close, but why is Windows taking one second for each joined thread instead of taking one second total?

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
Levi Muniz
  • 389
  • 3
  • 16
  • Can you show us the code to `ServerInit` (or at least an MVP of what the server thread does)? My guess is that Java is waiting for a (native) system call to return before throwing the interrupted exception. But maybe the code in `ServerInit` is doing something interesting. – selbie Jan 19 '17 at 06:39
  • I just edited the question to include the `ServerInit` code. – Levi Muniz Jan 19 '17 at 06:48
  • This is potentially a duplicate of another question, where the answer advised calling `ServerSocket#close` from another thread to signal exit for threads blocked in `ServerSocket#accept` by triggering a `SocketException`. http://stackoverflow.com/questions/2983835/how-can-i-interrupt-a-serversocket-accept-method – Chris Nauroth Jan 19 '17 at 06:49
  • 1
    Are you sure the problem is there rather than at the interrupt side of things? I suggest you add lots of logging with timestamps to see *exactly* where the problem is. – Jon Skeet Jan 19 '17 at 06:52
  • @ChrisNauroth I can't call `ServerSocket.close()` because of the scope of my `ServerSocket` instance, but I may be wrong. Jon, it works perfectly on macos and linux distros. – Levi Muniz Jan 19 '17 at 07:44
  • I think @Jon is right. Interrupting threads is difficult on Windows, so that's the most likely reason for the difference. – Harry Johnston Jan 20 '17 at 00:39
  • Working in one place but not another is a very good reason *to* add lots of logging with timestamps. Then you can compare the results for working and non working situations. – Jon Skeet Jan 20 '17 at 07:11
  • I added in a lot of debugging code.... It looks like the sockets are not working concurrently. I wrote code to output the status of `Thread.interrupted()` with every iteration. On mac, this prints 16 results every second. On windows, only one result is printed every second. Oddly, I can concurrently connect multiple clients using telnet. – Levi Muniz Jan 23 '17 at 17:15

0 Answers0