0

I am working on a Java client which has to send a heartbeat message periodically. I am using java.net.Socket for the work. My issue is even the server is stopped client goes on sending the messages without giving any exception.
I read various stackoverflow questions on this, but couldn't find the answer for my implementation. I read that only way to find the server is up is to try sending a message. But here I don't see a way to do this.
Here's how my class looks like.

public void process() {
    sendMessage(HEART_BEAT);
}

public void start(String serverAddress, int port) throws IOException {
    this.serverAddress = serverAddress;
    this.port = port;
    if (isConnected) {
        LOGGER.info("Already connected");
        return;
    }

    socket = new Socket(serverAddress, port);

    out = new PrintWriter(socket.getOutputStream(), true);
}

private void sendMessage(String message) {
     out.print(message + END_OF_MESSAGE);
     out.println();
}

Here's how my main method looks like,

public static void main(String args[]) {
     Client client=new Client();
     client.start("127.0.0.1", 900);
     while(true) {
          client.process();
          Thread.sleep(2000);
     }
}

How to implement a way to identify when the server has stopped?

Lasitha Yapa
  • 4,309
  • 8
  • 38
  • 57
  • @ScaryWombat You mean `BufferedWriter`, surely? A `ByteArrayOutputStream` doesn't have anything to do with a socket. – user207421 Jul 27 '18 at 02:01
  • @EJP, Yes you are right, I did not mean `ByteArrayOutputStream` - actually I was meaning to suggest that the OP writing directly to the `OutputStream` – Scary Wombat Jul 27 '18 at 02:13

2 Answers2

2

The PrintWriter may not throw any exception when wirting but that doesn't mean that it hasn't run on an error. The underlying OutputStream still throws an exception but it's internally caught and processed.
The original exception and information may be lost but the PrintWriter#checkError() method does still provide a way to check if something went wrong.
My suggestion is, to add some lines of code to your sendMessage method:

private void sendMessage(String message) {
     out.print(message + END_OF_MESSAGE);
     out.println();
     if ( pw.checkError() )
     {
       LOG.log( Level.SEVERE, "An error occured while writing.");
       shutdown(); // <-- method with the shutdown logic (e.g. closing the socket).
     }
}

Note that the PrintWriter#checkError() method also flushes the stream before checking if an error occured.

It may not be the most elegant solution but it get's the job done.

L.Spillner
  • 1,772
  • 10
  • 19
-6

Lose the PrintWriter. It swallows exceptions. Use a BufferedWriter, which doesn't. When you get an exception when sending, close the socket.

user207421
  • 305,947
  • 44
  • 307
  • 483