0

in my application I'm waiting for a server to be available in a loop:

Socket sock=new Socket(); // create the socket object
while (running)           // a more or less endless loop
{
   try
   {
      sock.connect(new InetSocketAddress(data.host,11355),1000); // try to connect to the server

      ...
      // when everything goes well, we do something with the "sock"

   }
   catch (IOException ioe)
   {
      // conection could not be established
      try
      {
         Thread.sleep(1000); // wait for one second until next connection attempt
      }
      catch (InterruptedException ie)
      {

      }
   }
}

The idea is to try to establish a connection to a server, when it fails an exception is thrown by connect() and I try again after a delay of one second.

My problem: it does not work. When the server is not available at application start-up but becomes accessible later, connect() is not successful, it can't connect to the server. This code works well only in case the server is available for the first connect().

So what could be wrong here? Do I have to reset the Socket somehow? Or what else could be the reason later calls to connect() never are successful?

Thanks!

Elmi
  • 5,899
  • 15
  • 72
  • 143
  • 2
    @LunarWatcher ?? He's not listening for client to connect but wants to connect *as* a client. – Fildor Sep 15 '17 at 12:28
  • 2
    @LunarWatcher What are you talking about? The server is at the other end. If it is not listening, connect will fail. That's exactly what happens here. Question is why it still fails when server becomes available. – Fildor Sep 15 '17 at 12:32
  • If this is a server issue, the server code should be added. – Zoe Sep 15 '17 at 12:34
  • "If this is a server issue" - it is not. – Fildor Sep 15 '17 at 12:35
  • Elmi: I see you only catch IOException. What about SocketTimeoutException? – Fildor Sep 15 '17 at 12:36
  • 2
    @LunarWatcher it is not a server issue, connecting to it works fine with other types of clients. And it would be great when you could be so kind to focus on the question instead of giving senseless comments – Elmi Sep 15 '17 at 12:36
  • @LunarWatcher what makes you think the server code should be added? That doesn't make a difference. The question is about the client's logic with some generic server. – f1sh Sep 15 '17 at 12:41
  • @Fildor: I only get a IOException. As soon as the server would be available it is a "Socket closed" - but on server side I can't see an incoming connection, accept() does not return anything. – Elmi Sep 15 '17 at 12:41
  • 1
    Hm, not sure if the state of the object stays in error state after an exception on connect. Have you tried simply doing `sock = new Socket();` in the catch block? – Fildor Sep 15 '17 at 12:44
  • @Fildor Yeah, that's it! The socket has to be created new every time...I wanted to avoid that to not to have too much load on the garbage collection but it seems to be mandatory...thank you! – Elmi Sep 15 '17 at 12:47
  • 2
    As stated in the API "Once a socket has been closed, it is not available for further networking use (i.e. can't be reconnected or rebound). A new socket needs to be created." – peterulb Sep 15 '17 at 12:55
  • 1
    I would care about GC when it becomes a problem. But I can feel your pain. Maybe there is a way to send an ICMP Ping before trying the connect. But that would only work if you knew the Server actually answers ICMP Pings ... – Fildor Sep 15 '17 at 12:55
  • @petul That's correct. I wasn't 100% sure if a failed connect closes the socket. – Fildor Sep 15 '17 at 12:57
  • Maybe see this answer: https://stackoverflow.com/a/7451251/982149 – Fildor Sep 15 '17 at 13:01

1 Answers1

1

The socket remembers its error state and cannot be used to retry a connect(). You have to create a new socket before every connect(). Sockets are cheap, so I would not worry about the overhead.

Alternatively you could try to ping the server before trying to connect(), but I do not think it is worth the effort (and it would also be less robust).

Johannes Overmann
  • 4,914
  • 22
  • 38