Monday, May 28, 2012

Android Sockets

So I thought that socket programming was going to be difficult for the Android platform. Turns out, Android uses the standard java.net.Socket API. So your basic Java socket program also applies to Android. Now if you are a Java programmer, then you'll know that there are two different ways of using sockets in the standard library provided by the JRE. There are a ton of other socket APIs out there, but they are third party. The JRE only comes with two APIs for sockets.

  1. The java.net.Socket API and related family
  2. The NIO way of doing it.

The old socket way was invented to mimic Unix sockets. The NIO way is much more complex and I've only done a little bit of programming in the NIO way, so I'm relived that Android uses the old socket API. Enough beating around the bush, let me show you a very basic example of a client using java.net.Socket.


package lan.testing.SimpleClient;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class SimpleClient extends Activity {

  private EditText messageSend;
  private TextView messageRecv;

  /**Setup all your GUI stuff */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
  
    messageSend = (EditText)findViewById(R.id.messagesend);
    messageRecv = (TextView)findViewById(R.id.messagerecv);
    Button buttonSend = (Button)findViewById(R.id.send);
    buttonSend.setOnClickListener(buttonSendOnClickListener);
  }

  Button.OnClickListener buttonSendOnClickListener = new Button.OnClickListener(){

    @Override
    public void onClick(View arg0) {
      Socket socket = null;
      DataOutputStream dataOutputStream = null;
      DataInputStream dataInputStream = null;

      try {
 socket = new Socket("192.168.99.1", 8888);
 dataOutputStream = new DataOutputStream(socket.getOutputStream());
 dataInputStream = new DataInputStream(socket.getInputStream());
 dataOutputStream.writeUTF(messageSend.getText().toString());
 messageRecv.setText(dataInputStream.readUTF());
      } 
      catch (UnknownHostException e) {
 e.printStackTrace();
      }
      catch (IOException e) {
 e.printStackTrace();
      }
      finally{
 if (socket != null){
   try {
     socket.close();
   }
   catch (IOException e) {
     e.printStackTrace();
   }
 }
  
 if (dataOutputStream != null){
   try {
     dataOutputStream.close();
   } 
   catch (IOException e) {
     e.printStackTrace();
   }
 }

 if (dataInputStream != null){
   try {
     dataInputStream.close();
   }
   catch (IOException e) {
     e.printStackTrace();
   }
 }
      }
    }
  };
}

That there is a basic client application that will send a message to 192.168.99.1 on port 8888 and then receive a reply back. The message to send is in a text edit box and the message received is placed in a text view widget. If you've ever taken a college course on Java Sockets then Android Sockets will make you feel right at home. Very little if anything is different between the two.

Next go round, I will create a socket and hold a telnet negotiation conversation with the server. Sorry if post seem to be stretched out. Company has me working on a tool for working with our vast store of XML documents, fun on the bun. Also, I'm still reading the RFC on the TN5250 stream format.

6 comments:

tec said...

I'm very familiar with Socket API but this Android GUI stuff is confusing. Also I've not tried NIO yet.

Justin said...

@Manish Raj:

The GUI stuff is a little confusing as it doesn't exactly follow the way standard Java things work.

The names give an indication as to what things should so. You can find out more here.

Unknown said...

What are the benefits of using sockets in Android, when HttpClient and UrlOppenConnection are also based on TCP ?

Unknown said...
This comment has been removed by the author.
Srini Vasudevan said...

@Manish Raj
You should try androidannotations. That makes the GUI lot more comprehendable. I hate how the android GUI works as it just makes your code very ugly and hard to follow.

Good article btw :)

Justin said...

@Стас Добрянский

HttpClient and Url.OpenConnection act at a higher level in the network stack.

HttpClient specifically works only with HTTP.

Url.OpenConnection works only with HTTP, HTTPS, JAR (A made up protocol to read Jar files), FILE (local browser), and FTP.

So yeah I would use either one of those if my client was strictly using one of those protocols.

However, if you need to work with a different protocol, either you have to get a library that wraps the protocol or you have to use sockets.