NewOne NewOne - 3 months ago 16
Java Question

How to make the client wait for the server socket connection?

I am using wifi direct to communicate between two mobile devices. I have setup sockets to send and receive messages. Everything works fine if I start the server device first(owner) and then the client device(member). I want to start any device in any order and still manage to send messages.

Currently, client waits for 5 secs and if no connection is available, then it stops looking for the server. I want the client to continue looking for the server even after time out till it finds the server connection. I have tried doing this and I am not successful yet in implementing this.

Initial client code:

@Override
public void run() {
Socket socket = new Socket();
try {
socket.bind(null);
socket.connect(new InetSocketAddress(address.getHostAddress(), SERVER_PORT), TIME_OUT);
socketCreator = new SocketCreator(socket, handler);
new Thread(socketCreator).start();
} catch (IOException e) {
e.printStackTrace();
try {
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return;
}
}


Modified like this:

@Override
public void run() {
Socket socket = new Socket();
try {
socket.setReuseAddress(true);
socket.bind(null);
while(!connectedToServer) {
try {
socket.connect(new InetSocketAddress(address.getHostAddress(), SERVER_PORT),
TIME_OUT);
socketCreator = new SocketReadWriter(socket, handler);
new Thread(socketCreator).start();
connectedToServer = true;
} catch (ConnectException e) {
Log.i(TAG,"Error while connecting. " + e.getMessage());
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
} catch (Exception e){
Log.i(TAG,"Exception "+e.getMessage());
}
}
} catch (IOException e) {
e.printStackTrace();
try {
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}


What is missing in my code? How can I make it work?

I am getting this error continuously:

Exception java.io.IOException: fcntl failed: EBADF (Bad file number)

Answer

You have to create a new Socket() every time. Failing to connect to the remote server closes the socket automatically. Since you are running this on Android - I guess you are not seeing the "Socket closed" error when trying to call connect twice.

@Override
public void run()
{
    connector: while (true)
    {
        try
        {
            Socket socket = new Socket();
            socket.connect(new InetSocketAddress("0.0.0.0", 9999), 2000);
            if(socket.isConnected())
            {
                  this.doSomethingElseWithConnectedSocket(socket);
                  break connector; // break out of the while loop
            }
            else
            {
                  socket.close()
            }
        }
        catch (ConnectException e)
        {
            e.printStackTrace(System.out);
            System.out.println("Unable to connect to server ");

            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e1)
            {
                // ignore
            }
        }
    }
}

public void doSomethingElseWithConnectedSocket(Socket value)
{
     value.close(); // close for no good reason
}