Wednesday, January 12, 2011

Simple communication using java.net.Socket

If you try it target to new version of Android, you will face the error of NetworkOnMainThreadException, refer to the post android.os.NetworkOnMainThreadException.
updated@2013-08-28



java.net.Socket provides a client-side TCP socket. It's a simple exercise to implement Socket communication, on Android as a client.

Simple communication using java.net.Socket

In the next exercises, I will implement a local Socket Server in Eclipse. Such that you can try the linking between Android device/emulator and the local socket server.

The server runs in local, so I have to know my IP, refer to last article "How to check my ip in Linux" to check your own ip. It's 192.168.1.101 in my case. Modify the code with your own ip.

socket = new Socket(< Your ip >, 8888);

package com.exercise.AndroidClient;

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 AndroidClient extends Activity {

EditText textOut;
TextView textIn;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
  
     textOut = (EditText)findViewById(R.id.textout);
     Button buttonSend = (Button)findViewById(R.id.send);
     textIn = (TextView)findViewById(R.id.textin);
     buttonSend.setOnClickListener(buttonSendOnClickListener);
 }

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

@Override
public void onClick(View arg0) {
 // TODO Auto-generated method stub
 Socket socket = null;
 DataOutputStream dataOutputStream = null;
 DataInputStream dataInputStream = null;

 try {
  socket = new Socket("192.168.1.101", 8888);
  dataOutputStream = new DataOutputStream(socket.getOutputStream());
  dataInputStream = new DataInputStream(socket.getInputStream());
  dataOutputStream.writeUTF(textOut.getText().toString());
  textIn.setText(dataInputStream.readUTF());
 } catch (UnknownHostException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 finally{
  if (socket != null){
   try {
    socket.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }

  if (dataOutputStream != null){
   try {
    dataOutputStream.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }

  if (dataInputStream != null){
   try {
    dataInputStream.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
 }
}};
}


main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 >
<TextView
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="@string/hello"
 />
<EditText
 android:id="@+id/textout"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 />
<Button
 android:id="@+id/send"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Send"
 />
<TextView
 android:id="@+id/textin"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 />
</LinearLayout>


Also, you have to grand permission for the App to access internet, by adding the code in AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>

download filesDownload the files.

Related:
- Android Server/Client example - server side using ServerSocket
- Android Server/Client example - client side using Socket

72 comments:

Gero O. said...

Hi! Nice article.
Ive been trying some different ways to get a page using Get and Post methods.
Ive tryed classic sockets, java.net.URLConnection and http components from org.apache.http...
Ive found that Apache Http Components and classic Sockets are very laggy and sometimes timeout when trying to connect to the remote web.
And URLConnection from java.net performs better for this task, but not outstanding.
After debugging a while i saw using Wireshark that almost 40% of packets sent are retransmissions and the 3way handshake of tcp doesn't or cant answer to SYN+ACK packets, only to SYN ones.
Have you heard about a bug or experienced something like this?
Have you a 1 or 2 sec lag in the connection stablishment in your tutorials?
Thanks!

viplov said...

Hi, Can i run this application using 2 PCs iv got 2 PCs conneted in LAN so of i run the Android Application in an emulator in one PC and the java program in another PC will i get the output?

Android Er said...

hello viplov,
I have tried to run a PC host server and a Android client running in emulator, both in the same PC. and another Android client connect via Wifi, it can work.

please refer Implement a simple Socket Server in Eclipse

viplov said...

ya iv too tried it iv got it thank you very much now i am trying it on an Android Device so now i am trying to modify the code so that i can use it for something like home automation purpose like phone to PC PC to a switching module and thank you once again

brouk said...
This comment has been removed by the author.
viplov said...

hi i am working on TCP communications using toggle buttons like i am using 2 buttons on click of one a message should go to the server so i have written a code but i am getting errors so shall i forward you the code can you help me in it?

Henry Daniel said...

Thank you so much, very nice article, it helped me a lot.

myself said...

Thank you for your post.

When i try to run this application on the android emulator in eclipse, it is forcing to close. I am not able to debug. What could the error be?
Thank you.

Android Er said...

hello myself,

Have you grant permission for the App to access internet, by adding the code in AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>

myself said...
This comment has been removed by the author.
myself said...

Yes I have placed it. What I am trying is to run the local server (that you wrote in the next exercise) and this application on the same pc. I tried all possible combinations, (localhost, my ip address, etc..)
(I am using eclipse classic 3.6.2, and my avd 5554). It is telling me fatal exception.
Sorry I am totally new to android :s
Thank you again.

myself said...

Thank you so much it worked!
The main.xml was outside the layout folder (i don't know how :s).
Great article :)

Bartek Boro Borowik said...

Thanks a lot! This article helped me a lot! I have got a simple newbie question though, if i for example send g-sensor data to this textOut editText, how can i loop this client, to send this data to pc in real time? Please help :) Thanks again!

Mercy said...

What a GREAT tutorial! I will be visiting your blog often!

mio said...

Hi
I am trying to use the same code but the Android client side always fails giving this exception:


07-18 18:39:13.177: WARN/System.err(16826): java.net.SocketException: The operation timed out
07-18 18:39:13.177: WARN/System.err(16826): at org.apache.harmony.luni.platform.OSNetworkSystem.connectStreamWithTimeoutSocketImpl(Native Method)
07-18 18:39:13.177: WARN/System.err(16826): at org.apache.harmony.luni.platform.OSNetworkSystem.connect(OSNetworkSystem.java:115)
07-18 18:39:13.177: WARN/System.err(16826): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:244)
07-18 18:39:13.177: WARN/System.err(16826): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:219)
07-18 18:39:13.177: WARN/System.err(16826): at java.net.Socket.startupSocket(Socket.java:781)
07-18 18:39:13.177: WARN/System.err(16826): at java.net.Socket.tryAllAddresses(Socket.java:194)
07-18 18:39:13.187: WARN/System.err(16826): at java.net.Socket.(Socket.java:258)
07-18 18:39:13.187: WARN/System.err(16826): at java.net.Socket.(Socket.java:222)
07-18 18:39:13.187: WARN/System.err(16826): at com.androidclient.AndroidClientNewActivity$1.onClick(AndroidClientNewActivity.java:47)
07-18 18:39:13.187: WARN/System.err(16826): at android.view.View.performClick(View.java:2408)
07-18 18:39:13.187: WARN/System.err(16826): at android.view.View$PerformClick.run(View.java:8817)
07-18 18:39:13.197: WARN/System.err(16826): at android.os.Handler.handleCallback(Handler.java:587)
07-18 18:39:13.197: WARN/System.err(16826): at android.os.Handler.dispatchMessage(Handler.java:92)
07-18 18:39:13.197: WARN/System.err(16826): at android.os.Looper.loop(Looper.java:144)
07-18 18:39:13.197: WARN/System.err(16826): at android.app.ActivityThread.main(ActivityThread.java:4937)
07-18 18:39:13.197: WARN/System.err(16826): at java.lang.reflect.Method.invokeNative(Native Method)
07-18 18:39:13.197: WARN/System.err(16826): at java.lang.reflect.Method.invoke(Method.java:521)
07-18 18:39:13.197: WARN/System.err(16826): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
07-18 18:39:13.197: WARN/System.err(16826): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
07-18 18:39:13.197: WARN/System.err(16826): at dalvik.system.NativeStart.main(Native Method)

any help?

mio said...

Ok even its working for me! it only worked when i switched n made the Android as Server n PC as Client.

nh said...

mio, how did you did you set that connection up? I am having trouble and i got the same timeoutexception that you did

Toto said...

hi sir, i'm a newbie in android Programming. what would be the cause if my emulator pops up a message "the Application testandroid(process com.test) has stopped unexpectedly. Please try again" i followed all the step you indicated in your post. tnx in advance...

بشير said...

Hi Toto, when you import the example try to select android 1.6 from the list called "Build Target" at form"New Android Project"
good luck

بشير said...
This comment has been removed by the author.
Nico said...

sir I found this problem when I try to run the emulator and it tells this
"the application___(process com.exercise.AndroidClient)has stopped unexpectedly. Please try again

Biscottis said...

Thank You, very very useful article.

For my student project, I want to develop a client-server app that allows restaurant customers to order food using an android tablet.

I've come to know that this is called 'socket programming',
Is this method feasible for the project i want to undertake?

I know i'm a total newbie in this, but i have time. I would like to know the right path to learn the skills necessary.

Andrea said...

Thank you so much this was really helpful! Please I want to know how i can let the android emulator acting as a server send a message back to the client. Does port forwarding also have to do with this? i really appreciate ur help because i need both to exchange msgs via tcp

tc said...

hello

thanks for nice article on socket communication...

i have a doubt about, how to receive data/message from other side

Craig said...

Hi,

I'm new to Android and Java. I am having a problem with your socket client example. I am using 2.3.3.

I get the error:

The method onClick(View) of type new View.OnClickListener(){} must override a superclass
method
- implements android.view.View.OnClickListener.onClick

Any ideas?

dantulio said...

Hi, me program hangs when it gets to de line dataInputStream.readUTF(). If i comment this line it works good but i need to read incoming data. help... thanks.. (sorry my english)

Android Er said...

hello dantulio,
Can you try to catch the Exception to see what happen? (ex. using a Toast to display the Exception.toString()).

Dan U. said...

I seem to keep getting an R.id cannot be resolved as a result of these three line:

textOut = (EditText)findViewById(R.id.textout);
Button buttonSend = (Button)findViewById(R.id.send);
textIn = (TextView)findViewById(R.id.textin);

Anymore insight as to what R.id does so I might better know how to fix this.

manjunath said...

hi all,
can any one send me code for establishing a socket connection between two emulator.. or private channel between two emulator...
please if not code also sugest me how to do.. its urgent..
reply u mail to this
manju.shirageri@gmail.com

crazystaby said...

Thanks for the tutorial. I am new to the android programming. I tried the source code and it works on the emulator and local PC, but when i deploy the apk into my android. It stuck at the screen and no response.. Anyone can help? Thanks

Binil Jacob said...

i was wondering if this works for 2.3.3 as well. and for all those who are really new , you need to edit your layout with ids textout and textin

Binil Jacob said...

@crazystaby i think you should check the android version on your phone..

trelodoc said...

hi everyone. i tried this code and the code for the server but when the android client runs, it crushes. any idea why? i tried many things but...

Binil Jacob said...
This comment has been removed by the author.
Andrea said...

Thank you. Thank you. Thank you.

really really informative and helpful.

HEMANT said...

thank you
above code is very use full me

Rodrigo Basniak said...

Hi,

First of all, very nice blog about android development you made! I'm starting now and found many interesting things here...

I tried to build this tcp client but android always crashes on the new socket line.

I changed it to my desktop's IP, checked if I can ping it from my Android phone and I can. I also can ping the phone from the desktop. I added the uses permission on manifest.

It crashes both on phone and the emulator.

If you have any idea I would be very grateful. I tried many socket codes from internet but they all crash when creating the new socket, so I think it's something very basic I missed, but no idea of what could be...

On emulator the stack is this:

02-29 01:26:01.724: D/dalvikvm(537): Not late-enabling CheckJNI (already on)
02-29 01:26:01.794: I/dalvikvm(537): Turning on JNI app bug workarounds for target SDK version 10...
02-29 01:26:02.644: D/gralloc_goldfish(537): Emulator without GPU emulation detected.
02-29 01:26:09.474: D/AndroidRuntime(537): Shutting down VM
02-29 01:26:09.474: W/dalvikvm(537): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
02-29 01:26:09.494: E/AndroidRuntime(537): FATAL EXCEPTION: main
02-29 01:26:09.494: E/AndroidRuntime(537): android.os.NetworkOnMainThreadException
02-29 01:26:09.494: E/AndroidRuntime(537): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
02-29 01:26:09.494: E/AndroidRuntime(537): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
02-29 01:26:09.494: E/AndroidRuntime(537): at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
02-29 01:26:09.494: E/AndroidRuntime(537): at libcore.io.IoBridge.connect(IoBridge.java:112)
02-29 01:26:09.494: E/AndroidRuntime(537): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
02-29 01:26:09.494: E/AndroidRuntime(537): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
02-29 01:26:09.494: E/AndroidRuntime(537): at java.net.Socket.startupSocket(Socket.java:566)
02-29 01:26:09.494: E/AndroidRuntime(537): at java.net.Socket.tryAllAddresses(Socket.java:127)
02-29 01:26:09.494: E/AndroidRuntime(537): at java.net.Socket.(Socket.java:177)
02-29 01:26:09.494: E/AndroidRuntime(537): at java.net.Socket.(Socket.java:149)
02-29 01:26:09.494: E/AndroidRuntime(537): at com.exercise.AndroidClient.AndroidClient$1.onClick(AndroidClient.java:44)
02-29 01:26:09.494: E/AndroidRuntime(537): at android.view.View.performClick(View.java:3511)
02-29 01:26:09.494: E/AndroidRuntime(537): at android.view.View$PerformClick.run(View.java:14105)
02-29 01:26:09.494: E/AndroidRuntime(537): at android.os.Handler.handleCallback(Handler.java:605)
02-29 01:26:09.494: E/AndroidRuntime(537): at android.os.Handler.dispatchMessage(Handler.java:92)
02-29 01:26:09.494: E/AndroidRuntime(537): at android.os.Looper.loop(Looper.java:137)
02-29 01:26:09.494: E/AndroidRuntime(537): at android.app.ActivityThread.main(ActivityThread.java:4424)
02-29 01:26:09.494: E/AndroidRuntime(537): at java.lang.reflect.Method.invokeNative(Native Method)
02-29 01:26:09.494: E/AndroidRuntime(537): at java.lang.reflect.Method.invoke(Method.java:511)
02-29 01:26:09.494: E/AndroidRuntime(537): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
02-29 01:26:09.494: E/AndroidRuntime(537): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
02-29 01:26:09.494: E/AndroidRuntime(537): at dalvik.system.NativeStart.main(Native Method)

Rodrigo Basniak said...
This comment has been removed by the author.
Binil Jacob said...

i hope everyone is using the android version 1.6 . got the same crashing problem while developing with 2.3.3

Rodrigo Basniak said...

Hum, I'm using 4.0.3, do things changed after 1.6?

Da Hu4wA said...

Hy!

NetWorkOnMainThread Exception ...

I found out that Ice Cream Sandwich wants every network communication to be done in a seperate thread, so this tut doesn't really work any more

Chanaka Fernando said...

Thanks mate....

Pilou said...

hello,
i'm a newbie in android, I'm under linux 12.04, eclipse and i try to communicate with my Android 2.2 phone using your application , but i get this error message in the eclipse console:java.net.socket exception: Network unreachable

SUSHIL PAUDEL said...

hello.....plzzz anyone can help make simple change in this project by making android as a server and desktop as a client!! Thanks.

pelao murdock said...

hi, i have been trying to implement the same program and it does not work. the graphical interface works ok, but when i send the data the program stops working and the emulator goes to the main page in the android emulator.
in order to make it run i had to make two changes:
1. change "AndroidClient" to "AndroidClientActivity" in public class AndroidClient extends Activity
2. i have to delete the "@Override" that is just over "public void onClick(View arg0) {"

i have installed android sdk and eclipse according to http://developer.android.com/sdk/installing.html.
finally, i am using the sdk=15 (which i have also changed in the manifest file).

can anyone tell me what i am doing wrong?
thanks, gus

Ali Rezaeian said...

Hi,
I have to use the android:targetSdkVersion="14" in my AndroidManifest.xml. But when i use it the program does not work ? what can I do? Thanks

Android Er said...

hello Ali Rezaeian,

Is it error of NetworkOnMainThreadException? Please read it: android.os.NetworkOnMainThreadException

Moubarak said...

hi i try to send different type of data like writeBytes and crash when i send that data

Sejal Shewaramani said...
This comment has been removed by the author.
Sejal Shewaramani said...

Thank you for the code.
But I have a doubt.
I have written the client in 2.2 and made a java project for the server. When I run the client on the emulator and the server code it works well. But I want to run the client on my phone. The client opened in my phone, but when I try to send the data, it doesnt go ahead. I connected my phone and laptop with WiFi. And in the laptop's web browser I wrote the IP of my laptop : <8888>
Am I doing this correctly? Please assist if I m wrong. And kindly tell why am I not able to send the data. My phone has version 2.3.6

-Sejal

Amila Ekanayake said...

Hi......
Thank you for this code...

I have a similar problem. I want to send a data (String) from PC(Laptop) to the android device. How can I do this? Thank you very much for your help.

- Amil

Dana said...

Hi,
I tried to run this application but when i click the send button on my emulator it just crashes and i get an error on the second @override below this line of code
Button.OnClickListener buttonSendOnClickListener
= new Button.OnClickListener(){
i would appriciate the help i have a project to do before my school starts thnx...

Monisha M said...

HI sir...i want to connect android client with tcp server in localhost to get a data....give some tutorial for that...
thank you...

Monisha M said...

i tried ur tutorial...but it shows some errors...plz clear that...
"Create field Textout in type id"
this is the error.
Thank u..

Monisha M said...

Hi..I Tried ur tutorial...but it shows some error...
"create field textout in type id:
This was the error...plz help to this ....
Thank u...

Monisha M said...

Hi..I Tried ur tutorial...but it shows some error...
"create field textout in type id:
This was the error...plz help to this ....
Thank u...

Sejal Shewaramani said...

@Monisha M: If you don't mind I would like to try to answer your question. have you added the EditText named textOut in the xml? check it in R.java if its declared in the id part.. cz your error suggests something like this..

elmediel said...

I made it possible! thanks for this post. Here is what ive done!

http://thedoraproject.blogspot.com/2012/12/data-connection-between-android-and-pc.html

sivakumar said...

Hi,
It is working fine for me when I followed the procedure that you mentioned in your article.

But When I try the reverse process where I created a ServerSocket in android and a socket in Java, the ServerSockets reads the data only once. After that I see the exception in Java console as "java.net.SocketException: Connection reset by peer: socket write error"
Could you please tell what the problem could be ??

Thanks!
Siva

Nicolas Mrad said...

I'm facing a problem, when i press send the app force closes! any suggestions?

Anonymous said...

nice tutorial,but how i can connect java server and android client via sms instead of sockets.

Anonymous said...

hey ! nice article
i have tried this one
i jsut got an IOException when trying to create a client socket...
what should i do.....?

thanx in advance

Anonymous said...

Okay I have been trying to run this program on an Android device.. but every time I have tried to send the message, it force closes. Do you have any suggestions?

Anonymous said...

waste of time

Anonymous said...

works perfectly!!

Anonymous said...

Hello there ,
thanks for this post , but i have a problem , how can I make 2 android devices talk with each other via texting , not from pc-android , I want android-android example , I hope you could help me with this issue

Regards ,

Wiem Rachman said...

I have tryed the code but, i did not get anyting in the server vice versa.

after change it

//dataOutputStream.writeUTF(textOut.getText().toString());
dataOutputStream.writeBytes(textOut.getText().toString());

//textIn.setText(dataInputStream.readUTF());
textIn.setText(dataInputStream.readByte());

i got the string at server side. but i still did not got anything at client side

Any idea?

bunny91 said...

Hi, I have a question. What IP should I use if I want to run this application from a real android phone, and not from the emulator. My computer is directly connected to internet, it's not connected through a wifi router. My phone is connecting through an wifi connection shared by my computer (I'm using connectify software to do this). So what IP should I use to make it work. I've tried some of them, but the application doesen't do anything, it eneters in a non responding state.
Please help me with this, I've seen that you tried this and worked for you.

Andr.oid Eric said...

I think you have to set port forwarding. But I don't know you config.

Hypic said...

Hello,

I would like to ask your help.
I tryed your client code and after connecting it did not get datas.
What is the problem. It it is possible can you give me the good codes. My mail address is schubertjw@gmail.com.
Than you....

Anonymous said...

Really interesting article .thanks a lot

gumuruhsspj said...

hi thanks for the tutorial. now i understand about the socket and the server concept in java.

I want to develop an app that will be deployed in two android devices for making them communicate through wifi. And here is the case:

Two devices are turning on their Wifi
They're not connected to any network. No LAN, no bluetooth, no phonecall, no internet
They want to discover each other devices
They want to communicate each other (sending simple string).
They don't want the intermediary devices for direct communication.
They are not having Wifi Direct capabilities.

is it possible? How to do that?

I read socket and server concept in java, but they need to be connected each other / to any networks. Which means it is not what in my case (above). I need to know how each device could discover each other first before connecting them. And how to do that in Wifi?

I found Chord SDK. that simplify the wifi coding in android. But that only available for Samsung device. Sigh.

I found JXTA for peer2peer communication on java. But it need RDV to list down the IP address for the peer to acknowledge each other. Which means not fit to my case (above).

I found alljoyn library. But the examples are too complex to follow.

I found NearBytes SDK. it simple code that makes the devices communicate each other. I like it. But it only available for shorter distance (few centimeters). Which is not fit to my case (above).

CMIIW.