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.

47 comments:

  1. 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?

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

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

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

    ReplyDelete
  5. 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:)

    ReplyDelete
  6. 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.

    ReplyDelete
  7. 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!

    ReplyDelete
  8. 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"...

    ReplyDelete
  9. 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";
    }

    ReplyDelete
  10. 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?

    ReplyDelete
  11. 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.

    ReplyDelete
  12. 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.

    ReplyDelete
  13. 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?

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

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

    ReplyDelete
  16. 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.

    ReplyDelete
  17. 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());

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

    ReplyDelete
  19. 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.

    ReplyDelete
  20. 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

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

    ReplyDelete
  22. Hello Nafees,

    client side using Socket is HERE

    ReplyDelete
  23. 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 ?

    ReplyDelete
  24. 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.

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

    can you help me with it?

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

    ReplyDelete
  27. 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

    ReplyDelete
  28. hello tags,

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

    ReplyDelete
  29. 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

    ReplyDelete
  30. 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.



    ReplyDelete
  31. 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

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

    ReplyDelete
  33. 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!

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

    ReplyDelete
  35. 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

    ReplyDelete
  36. 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.

    ReplyDelete
  37. 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?

    ReplyDelete
  38. 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.

    ReplyDelete
  39. hello /\ B H !,

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

    ReplyDelete
  40. Nice tutorial...Loved it

    ReplyDelete
  41. hi,
    i have a big problem. i use usb-Ethernet adapter instead of wifi and connect my android device(192.168.9.1)
    with Ethernet cable to my laptop(192.168.9.2).i can ping devices from both side.
    i use server side program on my android device(HTC One root).
    when i try to connect to server with my laptop (telnet 192.168.9.1 33333) it is not possible and telnet wait until timeout.
    i check my android device with OS monitor . server program start and it LISTEN to 192.168.9.1 port 33333 but does not receive any connection.
    when i use wifi network every thing OK and i can connect to server.
    do you have any idea about it ?

    ReplyDelete
  42. Can you quickly share the repo link?

    ReplyDelete
  43. Android chat is also very important thing to integrate in apps. We should have the knowledge about visitors like from where they are coming?,location, referral etc.

    ReplyDelete
  44. Thank you. you saved my day...

    ReplyDelete