views:

51

answers:

0

I am working on a distributed application that communicates over socket connections. I'm not sure if this matters with the problem but it is a Netbeans RCP application.

There are 2 different client sides of it which simply display the status of their connection to the server, send requests to the server side and display the responses received through the socket

The server side of it opens up a server socket, then, in a while loop, passes the serverSocket.accept() socket into its own thread to be processed. Whenever we run the application (with the network available on startup) everything works: when the network is killed the client side displays the "server unavailable" message and whenever the network is connected this message goes away and the status is displayed correctly.

The problem is this, whenever we start the program without a network connection - it initially displays the "server unavailable" message correctly - but whenever the network comes back up the message goes away but the socket read times out and the status is never updated.

on both client & server sides i get the error java.net.SocketTimeoutException: Read timed out.

i'm wondering what could make it so that if the application starts without network connection the sockets are never able to read from each other correctly. if it helps i also occasionally get an EOFException thrown between the SocketTimeoutExceptions. to make things even better the EOFException is thrown completely randomly.

Any help on this would be greatly appreciated


This is my first post on stack overflow and I was not sure how to add this in a separate box under the comments

We basically run on a system where the network cuts in and out constantly – and we have to account for the network not being available at start up and randomly while running.

@Steve Emmerson – You are correct. when we startup with no Network Connection or we try reading from a dead connection we throw an Exception – we use this to determine that the connection is down and display the correct message in the client side. On the server side though we actually don’t get any exception thrown until after the network comes back up and the socket server accepts.

Here is the server code I’m using

private final class MessageServerCreatorThread extends Thread {

    private final ServerSocket serverSocket;

    public MessageServerCreatorThread() {
        ServerSocket ss = null;
        try {
            ss = new ServerSocket(LOGGER_MESSAGE_PORT);
            ss.setReuseAddress(true);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        this.serverSocket = ss;
    }

    @Override
    public void run() {
        while (true) {
            try {
                new LoggingStatusMessageServer(serverSocket.accept()).start();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

@Both

The stack trace for the server side is:

java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:129) at java.net.SocketInputStream.read(SocketInputStream.java:182) at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2249) at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2542) at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2552) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351) at ecdu.logger.status.LoggingStatusMessageServer.run(LoggingStatusMessageServer.java:58)

and the code for the LoggingStatusMessageServer is:

@Override
public void run() {
    try {
        final ECDULogger logger = ECDULogger.getInstance();
        socket.setSoTimeout(SOCKET_SO_TIMEOUT);
        ois = new ObjectInputStream(socket.getInputStream());
        oos = new ObjectOutputStream(socket.getOutputStream());
        oos.flush();

        while (true) {
            final Object request = ois.readObject();
            if (request instanceof . . .) {
                . . . (processing request)
            }
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        cleanup();
    }
}

The stack trace on the client side is:

java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:129) at java.net.SocketInputStream.read(SocketInputStream.java:182) at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2249) at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2542) at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2552) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351) at ecdu.logstatus.network.LogStatusReaderThread.processResponse(LogStatusReaderThread.java:125) at ecdu.logstatus.network.LogStatusReaderThread.run(LogStatusReaderThread.java:89)

and the code for the reader thread is: (This is complete legacy code and is definitely not clean by any means)

private void processResponse() {
    try {
        final Object response = ois.readObject();
        if (response instanceof . . .) {
            . . . (process response)
        }
    } catch (IOException ex) {
        ex.printStackTrace();
        log.error("IO exception processing response: " + ex.getMessage());
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException ex1) {
            } finally {
                socket = null;
            }
        }
        connect();
    } catch (ClassNotFoundException ex) {
        log.error("Class not found exception processing response: " + ex.getMessage());
    } catch (NullPointerException ex) {
        ex.printStackTrace();
        log.error("Null pointer exception processing response: " + ex.getMessage());
        socket = null;
        connect();
    }
}

Everything seems to function fine when we're connected to the network at start up - we can disconnect and reconnect at any time and the status will be updated correctly. These exceptions are only thrown when we're not connected to the network at start up - then both sides reads just time out forever when the network comes back (at first when it's still disconnected the status is displayed correctly - when we lose connection again it's displayed correctly - just nothing displays when we're connected). I'm also wondering - do you think that the Netbeans RCP could be contributing to this in any way ??? i don't see why it would but i'm just wondering.