Saturday, February 8, 2014

Android Server/Client example - server side using ServerSocket

It's the server side implementation of our Server/Client example, the client side is listed in next post "client side using Socket".

Android Server using ServerSocket
Android Server using ServerSocket
In this server side implementation, it will list its own IP address when program start. And run in background thread, start a ServerSocket and wait at serverSocket.accept(). Once any request received, it return a message to client side.

package com.example.androidserversocket;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;

import android.os.Bundle;
import android.app.Activity;
import android.widget.TextView;

public class MainActivity extends Activity {

 TextView info, infoip, msg;
 String message = "";
 ServerSocket serverSocket;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  info = (TextView) findViewById(R.id.info);
  infoip = (TextView) findViewById(R.id.infoip);
  msg = (TextView) findViewById(R.id.msg);
  
  infoip.setText(getIpAddress());

  Thread socketServerThread = new Thread(new SocketServerThread());
  socketServerThread.start();
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();

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

 private class SocketServerThread extends Thread {

  static final int SocketServerPORT = 8080;
  int count = 0;

  @Override
  public void run() {
   try {
    serverSocket = new ServerSocket(SocketServerPORT);
    MainActivity.this.runOnUiThread(new Runnable() {

     @Override
     public void run() {
      info.setText("I'm waiting here: "
        + serverSocket.getLocalPort());
     }
    });

    while (true) {
     Socket socket = serverSocket.accept();
     count++;
     message += "#" + count + " from " + socket.getInetAddress()
       + ":" + socket.getPort() + "\n";

     MainActivity.this.runOnUiThread(new Runnable() {

      @Override
      public void run() {
       msg.setText(message);
      }
     });

     SocketServerReplyThread socketServerReplyThread = new SocketServerReplyThread(
       socket, count);
     socketServerReplyThread.run();

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

 }

 private class SocketServerReplyThread extends Thread {

  private Socket hostThreadSocket;
  int cnt;

  SocketServerReplyThread(Socket socket, int c) {
   hostThreadSocket = socket;
   cnt = c;
  }

  @Override
  public void run() {
   OutputStream outputStream;
   String msgReply = "Hello from Android, you are #" + cnt;

   try {
    outputStream = hostThreadSocket.getOutputStream();
             PrintStream printStream = new PrintStream(outputStream);
             printStream.print(msgReply);
             printStream.close();

    message += "replayed: " + msgReply + "\n";

    MainActivity.this.runOnUiThread(new Runnable() {

     @Override
     public void run() {
      msg.setText(message);
     }
    });

   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    message += "Something wrong! " + e.toString() + "\n";
   }

   MainActivity.this.runOnUiThread(new Runnable() {

    @Override
    public void run() {
     msg.setText(message);
    }
   });
  }

 }

 private String getIpAddress() {
  String ip = "";
  try {
   Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
     .getNetworkInterfaces();
   while (enumNetworkInterfaces.hasMoreElements()) {
    NetworkInterface networkInterface = enumNetworkInterfaces
      .nextElement();
    Enumeration<InetAddress> enumInetAddress = networkInterface
      .getInetAddresses();
    while (enumInetAddress.hasMoreElements()) {
     InetAddress inetAddress = enumInetAddress.nextElement();

     if (inetAddress.isSiteLocalAddress()) {
      ip += "SiteLocalAddress: " 
        + inetAddress.getHostAddress() + "\n";
     }
     
    }

   }

  } catch (SocketException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   ip += "Something Wrong! " + e.toString() + "\n";
  }

  return ip;
 }
}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/infoip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <TextView
            android:id="@+id/msg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </ScrollView>

</LinearLayout>

Remark: uses-permission of "android.permission.INTERNET" is needed.

download filesDownload the files.



*** Updated example: Bi-directional communication between Client and Server, using ServerSocket, Socket, DataInputStream and DataOutputStream.

42 comments:

Peter said...

Thanks, great examples! Works perfectly when devices are in a local network.
I tried with one device connected using 3G and the other using Wifi, but it didn't work. Any idea why?

Andr.oid Eric said...

I think you have to set port forwarding on your router.

Dominique said...

In the Server example, you start the socketServerReplyThread by calling run() instead of calling start(). Isn't it a misuse of a thread?

Sourav Suman said...

how to connect and test? please help....

Andr.oid Eric said...

Hello Dominique,

Thx for yuor concern.

My point is all network processing should run in background thread. In my implementation, socketServerReplyThread.run() from SocketServerThread, that means both SocketServerThread and SocketServerReplyThread run in a common background thread. I have no idea about any advantage/disadvantage to run in ONE common background thread, or to run in TWO separate background.

Any further advice is welcome:)

Andr.oid Eric said...

hello Sourav Suman,

Please view the video in last post Android Server/Client example - client side using Socket.

In my test, both client and server run in a common WiFi network, such that no need to concern port forwarding in router.

Tales Bragança said...

In my test, Server crashs, so i created a server in my computer using Perl, i tried to connected using client from my Phone and client return:

IOException.java.net.SocketException: No route to host

You know that is this ? Thanks!

Andr.oid Eric said...

hello Tales Bragança,

Can you make sure your server is reachable? for example, both the server and client are in the same network. Your App have permission of "android.permission.INTERNET"...

Subramanian P V said...

Hi,

I have a query . if the client wants to say hello to server. or send any msg how to get it in server. is it possible to add a inputstream reader the server thread. I just to read it but the socket connection is closed

BufferedReader in1 = new BufferedReader(new InputStreamReader(hostThreadSocket.getInputStream();
if (in.ready()) {
String s = in1.readLine();
System.out.println("manga");
message+= "replayed: " + msgReply + " "+"server request: "+s;
}
else{
message+= "replayed: " + msgReply + "\n"+"server request";
}

senurz said...

I tried to connect two devices through wifi-direct using this. but i am getting an ConnectException (Network is unreachable)
can you help me with that?

Pushpal Roy said...

Hello this is Pushpal Roy. I liked your example.. I tried it too. I created a hotspot in one phone, and connect by wifi to another phone. But its not working. Please help.

Andr.oid Eric said...

hello Subramanian P V,

Please check the upadted example: Bi-directional communication between Client and Server, using ServerSocket, Socket, DataInputStream and DataOutputStream

hello senurz,
I don't know how to connect with WiFi direct.

hello Pushpal Roy,
I tried to use on WiFi spot, it work. Please check the second video on the above link.

Pushpal Roy said...

Thank you so much. :) I saw the video of bidirectional communication. And also implemented it successfully. :)

But, I'm working on a project in were I need to broadcast a message from the server (for say)to multiple clients connected in the same network. Or any of of the clients to other clients and the server. Actually I'm building a Wi-Fi group chat. Can you please help me in this?

Andr.oid Eric said...

hello Pushpal Roy,

please check:
Implement simple Android Chat Application, server side and client side.

hope can help:)

Pushpal Roy said...

Saw your broadcasting tutorial... Its just awesome!! Thank you so much!

And Droid said...

I am not able to download the code.
Please suggest!!

黃小右 said...

I'm trying to implement smartphone to PC socket. I tried my best to write but still not work. Can you give me some help??

My example is"Server=Smartphone(Android), Client=PC(java)" And can send or response some messages

Thanks.

Anonymous said...

HI, I get the following error:

Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

for this line:

infoip.setText(getIpAddress());

Andr.oid Eric said...

hello 黃小右,

please read updated examples Bi-directional communication between Client and Server, using ServerSocket, Socket, DataInputStream and DataOutputStream and Java/JavaFX Client link to Android Server.

fazil sheriff said...

Thanks its working fine for WiFi .Do you have any tutorial for same concept for blue tooth.

Andr.oid Eric said...

hello fazil sheriff,

I'm just doing it: Bluetooth communication between Android devices.

Honestly, it is not a good working example, but may be easy to understand.

Mallik said...

Hello,

I need to communicate between android code and JavaScript code(webView) of same application.
My implementation is as follows,
1. Created serverSocket connection in android as described in your example code. Start this server in onCreate of Activity.
2. Created websocket connection in JavaScript code.

Result:
I am able see some messages being read in serverSocket read() method. Data is related websocket creation details
(http header, connection upgraded to socket, user agent, etc) But I try to send some message to websocket from serverSocket(android code). It is not working.

Note: ServerSocket is listening to port 8080.
Websocket is cerated using URL - "wb:127.0.0.1:8080"

Please let me know if my approach is wrong.

Is it possible to communicate between serverSocket and webSocket?

Mallikarjun

Nafees said...

Sir where is Client said code?
how to send message one client to other using server in between multiple clients on android

Andr.oid Eric said...

Hello Nafees,

client side using Socket is HERE

Karthik Rao said...

Great tutorial. I am trying to connect 2 android devices over a tethering wi-fi network. But client side is showing connection refusesd. I've added the network permissions in the manifest file as well. Anything I am missing ?

Anonymous said...

Sir I need android codings to send the messages to the server and I have to read it from my app through the server.Please help me sir.

IAmABeginner said...

i have pasted your code but it says "Something wrong! java.net.SocketException

can you help me with it?

Monika Gupta said...

This post is likeable, and your blog is very interesting, congratulations :-)

tags said...

i am a newbie on android so i just copy and paste it to my project but my prolblem now is how to run this chat application?. .anyone can help me? .thank you

Andr.oid Eric said...

hello tags,

Just connect both mobile to the same WiFi router, suppose it work. Refer to the video.

M. Jalil said...

Hello Andr.oid Eric,

I wanted to ask about the port forwarding. Do you know a good tutorial I can follow to understand how to implement that? Does that mean my server must remain connected to the same router though?
If you don't mind, may you please take a look at my question on StackOverFlow and try to help me? Any advice or guidance would be greatly appreciated.

http://stackoverflow.com/questions/33154590/server-on-android-reachable-from-devices-not-on-local-network

Thanks!
Best Regards,
M. Jalil

Andr.oid Eric said...

M. Jalil,

Just found a good tutorial: http://www.howtogeek.com/66214/how-to-forward-ports-on-your-router/

It mainly depends on your router setting, if your server behind router of HOME network.

IF your server is in MOBILE network, it's another case: most probably the ISP will block your ports.



Ed said...

Hello Eric
congratulations for your blog.
When I run the server side of your project, it loads but with a message that says "something wrong ......"
In your code:
Enumeration enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
gets that message.

would youn tell me, please, the origen of that wrong doing?

Thanks in advance

Sathish Kumar said...

sir how to save to save the datas from the server socket to database.

YO! said...

Hi I have 2 QUESTIONS:-
1. I am able to run SERVER from phone and CLIENT from Emulator... but i am not able to receive any communication when i run SERVER on emulator and CLIENT on phone... why? shouldnt it work both ways?

2. When i Disconnect my phone from WIFI... then the emulator is not able to connect when i am on my regular 3G network? I cant seem to understand...

It would be nice if you could shed some light on this logic
thanx,
YO!

Andr.oid Eric said...

hello YO!
Sorry, I don't know how the emulator config!

Hands on Science - SAI said...

hello andr.oid Eric,
Your tutorial and blog is awesome as it helped me a lot in creating a server client communication. But it works when the two devices are connected to same network. Do you have any tutorial to connect over different routers? (through IP)

Regards,
Subramanya

Andr.oid Eric said...

Hello Hands on Science - SAI,

To connect over different routers; I think it very depends on router setting, specially port forwarding. It's very hard to explain for me.

It's a very good tutorial Port forwarding on your router, a suggested tutorial.

Pratik_Mehkarkar said...

hello sir , i am having hostinger,s server by using this server i want to implement the android chat application. in chat application the client must use the server as hostinger server .sir plz help me that how can i do this?

/\ B H ! said...

hi,
I would like to know one thing(client and server are 2 different projects/apps)
line1 outputStream = hostThreadSocket.getOutputStream();
line2 PrintStream printStream = new PrintStream(outputStream);
line3 printStream.print(msgReply);
line4 printStream.close();

if line3 printstream.print(msgReply) which is server side code is sending some useful message to client.
Now if i want to use that message in my client program, how can i ?
How can i save that message in client project in a variable or anything else? please help.

Andr.oid Eric said...

hello /\ B H !,

Refer to the client side Android Server/Client example - client side using Socket: where response in MyClientTask is the message received.

Anonymous said...

Nice tutorial...Loved it