4

I have a program running on a server (Server A) which listens on one port for an external connection (from an external server, B), then listens on another port for an internal connection on the same server (Server A). It then passes data from the internal to external connection and back again.

I want to know if there is a way I can detect that the client external was disconnected. I just need one external connection at a time, but I would like to be able to accept a new one if the external client reboots or something like that.

This socket level stuff is all fairly new to me, so if there is a better way of going about this, I'm all ears. The one stipulation is that the client running on Server B must be the one to initiate the connection and the connection must live for as long as possible.

public void handleConnection() {
    System.out.println("Waiting for client message...");
    try {
        SSLSocket extSocket = (SSLSocket) this.externalServerSocket.accept();

        ObjectInputStream externalOis = new ObjectInputStream(extSocket.getInputStream());
        ObjectOutputStream externalOos = new ObjectOutputStream(extSocket.getOutputStream());
        System.out.println("Client connection establisthed");
        // Loop here to accept all internal connections
        while (true) {

            SSLSocket internalSocket = (SSLSocket) this.internalServerSocket.accept();
            new ConnectionHandler(externalOis, externalOos, internalSocket);

        }
    } catch (IOException e) {
        System.err.println(e.getMessage());
        return;
    }
}

class ConnectionHandler implements Runnable {
    private SSLSocket internalSocket;

    private ObjectOutputStream internalOos;
    private ObjectInputStream internalOis;

    private ObjectInputStream externalOis;
    private ObjectOutputStream externalOos;

    public ConnectionHandler(ObjectInputStream externalOis,
            ObjectOutputStream externalOos, SSLSocket internalSocket) {

        this.internalSocket = internalSocket;

        try {
            this.internalOis = new ObjectInputStream(this.internalSocket.getInputStream());
            this.internalOos = new ObjectOutputStream(this.internalSocket.getOutputStream());

            this.externalOis = externalOis;
            this.externalOos = externalOos;

        } catch (IOException e) {
            System.err.println(e.getMessage());
        }
        new Thread(this).start();
    }

    @Override
    public void run() {
        try
        {

          // process data
          Object o = internalOis.readObject();
            externalOos.writeObject(o);
            Object o2 = externalOis.readObject();
            internalOos.writeObject(02);

            internalOos.close();
            internalOis.close();

            this.internalSocket.close();

        } catch (IOException e) {
            System.err.println(e.getMessage());
        } catch (ClassNotFoundException e) {
            System.err.println(e.getMessage());
        }
    }
}
Korra
  • 489
  • 3
  • 8
  • 20
  • 1
    Make the server ping it's clients in a round-robin fashion... as soon as any client drops three pings you disconnect him. Think of a conversation on a phone where the line gets cut off - none of the participants expects it and is able to say 'goodbye' anymore. – Shark Oct 03 '12 at 14:49

1 Answers1

0

If the client disconnects, readObject() will throw EOFException, and write() will throw an IOException: connection reset. That's all you need.

user207421
  • 305,947
  • 44
  • 307
  • 483