2

I made android application that connects to remote server and send some data. Remote server is Windows application.

Connection method:

private void ConnectToMonitor() {
    try {
        s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT);
    } catch (UnknownHostException e) {

        e.printStackTrace();
    } catch (IOException e) {

        e.printStackTrace();
    } finally {
        try {
            s.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

This works perfectly if server is online. Application is sending data and server is receiving. But if server is offline android app. is blocked. My question is how to handle this? How to continue with application and avoid error even the server is down?

Adil Shaikh
  • 44,509
  • 17
  • 89
  • 111
Josef
  • 2,648
  • 5
  • 37
  • 73

3 Answers3

3

Remember to call this outside the UIThread. Follow this tutorial. In android all connections need to be managed outside the UIThread, in the tutorial I linked you will find easy ways to post your results back to the UI (handlers, asynctasks...)

Of course we don't know if the problem is about the thread with just the given code, but it is the most usual error.

Neron T
  • 369
  • 2
  • 8
2

First remember to set the socket timeout :

mSocket.setSoTimeout(timeout); //in milliseconds

You can however specify different timeout for connection and for all other I/O operations through the socket:

private void connectToMonitor() {
    try {
        socket = new Socket();            
        InetAddress[] iNetAddress = InetAddress.getAllByName(SERVER_ADDRESS);
    SocketAddress address = new InetSocketAddress(iNetAddress[0], TCP_SERVER_PORT);

        socket.setSoTimeout(10000); //timeout for all other I/O operations, 10s for example
        socket.connect(address, 20000); //timeout for attempting connection, 20 s
    } catch (UnknownHostException e) {

        e.printStackTrace();
    } catch (IOException e) {

        e.printStackTrace();
    } finally {
        try {
            socket.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Second, in Android, you should perform any network I/O in separate threads!

As an example, using regular Java Threads :

String threadName = getClass().getName() + "::connect";     
    new Thread(new Runnable() {         
        @Override
        public void run() {
            connectToMonitor();
        }
    }, threadName).start();
ehanoc
  • 2,187
  • 18
  • 23
  • Sorry, but something is wrong with this code for threads. Is the syntax ok because syntax editor shows mistakes.. – Josef Jun 14 '13 at 13:04
  • @Josef this code is correct. Where are you calling this ? Try using it on your activity's onCreate() or onResume() as an experiment. See if it works there. Also note that your method name is ConnectToMonitor and really should be connectToMonitor(). – ehanoc Jun 14 '13 at 13:07
  • Now it works fine, it doesn't freeze application anymore. Now I want to make check if server is online or not. If not try to connect. To achieve that i made runnable outside onCreate() and start thread by pressing button start. Thread needs to execute each 5 seconds so the code looks like: Runnable r = new Runnable() { @Override public void run() { while (serverConnection == true) { try { Thread.sleep(5000); ConnectToMonitor(); } catch (InterruptedException e) { e.printStackTrace(); }}}}; But this doesn't work – Josef Jun 17 '13 at 06:54
  • @Josef Hey Josef, that's a totally different issue. And it's hard to say without seeing more code. I suggest you research a little bit; if you don't find an answer start a new topic. I'll check it out. – ehanoc Jun 17 '13 at 07:02
  • All I need is to check connection to server every X seconds. If server is down then reconnect. I have tried with Timer by starting from onCreate(...) and execute each 3000 ms. Nothing happens. My server app is Windows desktop app and it listen on port 8890 and just receives information from clients. If server app is started that it works fine, but If i close connection and start again clinent app (android app) doesn't check connection. Only for the first time when is stared. – Josef Jun 17 '13 at 10:38
  • @Josef, this gets into depth of threading & network/socket programming. I suggest you research a bit and/or post a new question about it on SO. But, i can tell you, you should probably look into : http://stackoverflow.com/questions/1443166/android-how-to-check-if-the-server-is-available . But you also state that you wanna manage the connectivity(disconnections, broken connections, reconnecting), which requires you to implements mechanisms to detect broken connections at the application level. Also, flag this topic as "answered",if any of the answers helped you solve the issue described above. – ehanoc Jun 17 '13 at 10:52
0

You can set A timeout for the socket. Use Socket.setSoTimeout method

socket.setSoTimeout(timesinmilis);

by using this your socket will throw a socket timout exception. You can catch that and do what you want

stinepike
  • 54,068
  • 14
  • 92
  • 112
  • I put timeout at 5000 ms. Socket Timeout exception is already handled by the catch block for IOException... But how to continue with application after timeout? The thing I want to achieve is when activity start, check connection. If there is no connection continue with application normally. Now application gives me only error message to wait or close app. – Josef Jun 14 '13 at 12:25
  • 1
    @Josef In Android, you should do all network I/O operations on separate threads! – ehanoc Jun 14 '13 at 12:44