Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any callback mechanism in android when there is data available to read in socket

Well I am familiar with socket programming in c, iOS environment..But now trying to connect my android and my remote server via sockets...As a start up, I wrote a simple server program in C and ran it on my desktop which patiently wait for a connection request, accepts connection, then wait for some request string, and on getting the request string returns some response string, then again wait for next request and go on..Well you get the idea..

So far

  1. I have established a connection with my android and server
  2. sent and received data

And this is my client code..

public class SocketMaster {
    private Socket clientSocket     =   null;
        BufferedReader socketReadStream =   null;
    public boolean connectToHost(String ip, int port){
        try {
            InetAddress serverAddr  =   InetAddress.getByName(ip);
            try {
                clientSocket        =   new Socket(serverAddr, port);
                socketReadStream    =   new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                String line     =   null;
                String stringToSend =   "This is from client ...Are you there???";

                //Write to server..stringToSend is the request string..
                this.writeToServer(stringToSend);

                //Now read the response..
                while((line = socketReadStream.readLine()) != null){
                    Log.d("Message", line);
                }
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public boolean writeToServer(String stringToSend){
        DataOutputStream dos        =   null;
        try {
            dos                         =   new DataOutputStream(clientSocket.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        try {
            dos.write(stringToSend.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
}

I create an object of SocketMaster from another activity and calls connectToHost passing ip and port of server..Everything works fine and I am able to connect, send and receive data..

Now my question is regarding these lines

//Now read the response..
while((line = socketReadStream.readLine()) != null){
     Log.d("Message", line);
}

From what I understand, the thread that executes this code

  • blocks until there is data to read
  • if data available, read it, then because of loop again blocks until next chunk of data arrives

Simply I can't run this code on main thread as it will block my UI Activities..I can think of running this in a background thread, which is one option...

But Ideally what I want is...

A callback (I think, listener in android terms, anyone familiar with iOS CFSocket and callback),method , which gets called when there is data available to read, so that I can just read data and then return..

Is there any such mechanism in android/ java...If not ( :-( ), can anyone link me to some example where socket handling is done in background...

EDIT: I was not asking about creating a callback mechanism myself..I was just asking is there any listener present which notify you when there is data to read, when the connection got disconnected..Thus I can eliminate the above given while loop...If there isn't any callback, I am ready move this socket to another thread, which loops arounds and reads data (which infact I have already done)...

**

EDIT Bounty time again..

**

Well I am 2 weak old android/java developer with a good 3.5 years of c/c++/objective c development experience behind that... So I have seen low level c native sockets (which blocks(configurable) when use read() and recv()) and apple's CFSocket (which is C socket itself but provide a wrapper to provide callback mechanism).. I am not asking about coding a callback mechanism myself here (which I am whole heartedly ready to do if there is no readymade alternative present, but why reinvent the wheel again?)...I am beginning to understand java as very advanced and high level platform.. I thought there should be some higher level wrapper library lurking around..So I am thinking of increasing the audience to this thread by starting a bounty..

like image 685
Krishnabhadra Avatar asked Jul 30 '11 07:07

Krishnabhadra


1 Answers

There is no ready-made callback for this in Java. You can easily implement one using the classes in the NIO package. You mostly need Selector and SocketChannel. If you are familiar with select(2), should be easy to follow. If not, try a NIO tutorial.

http://download.oracle.com/javase/1.5.0/docs/api/java/nio/channels/SocketChannel.html http://download.oracle.com/javase/1.5.0/docs/api/java/nio/channels/Selector.html

In any case, you will have to poll the socket to check if there is data, and you can't do this on the main thread. Unless your android app should manage multiple connections on the same thread, it might be a lot easier to just use blocking IO. Another thing to consider: if this has to run continuously/for a long time you need to move it to a service. Even then, the OS can kill it, if it runs out of resources, so be ready to handle reconnects.

HTH

like image 178
Nikolay Elenkov Avatar answered Oct 17 '22 03:10

Nikolay Elenkov