Saturday, August 16, 2014

Implement simple HTTP server running on Android

Example to implement simple HTTP server on Android:


MainActivity.java
package com.example.androidhttpserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
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.support.v7.app.ActionBarActivity;
import android.widget.EditText;
import android.widget.TextView;
import android.os.Bundle;

public class MainActivity extends ActionBarActivity {

 EditText welcomeMsg;
 TextView infoIp;
 TextView infoMsg;
 String msgLog = "";
 
 ServerSocket httpServerSocket;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  welcomeMsg = (EditText) findViewById(R.id.welcomemsg);
  infoIp = (TextView) findViewById(R.id.infoip);
  infoMsg = (TextView) findViewById(R.id.msg);

  infoIp.setText(getIpAddress() + ":" 
   + HttpServerThread.HttpServerPORT + "\n");

  HttpServerThread httpServerThread = new HttpServerThread();
  httpServerThread.start();
 }
 
 @Override
 protected void onDestroy() {
  super.onDestroy();

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

 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;
 }
 
 private class HttpServerThread extends Thread {
  
  static final int HttpServerPORT = 8888;

  @Override
  public void run() {
   Socket socket = null;
   
   try {
    httpServerSocket = new ServerSocket(HttpServerPORT);
    
    while(true){
     socket = httpServerSocket.accept();

     HttpResponseThread httpResponseThread = 
      new HttpResponseThread(
       socket, 
       welcomeMsg.getText().toString());
     httpResponseThread.start();
    }
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }

  }

  
 }
 
 private class HttpResponseThread extends Thread {
  
  Socket socket;
  String h1;
  
  HttpResponseThread(Socket socket, String msg){
   this.socket = socket;
   h1 = msg;
  }

  @Override
  public void run() {
   BufferedReader is;
   PrintWriter os;
   String request;
   
   
   try {
    is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    request = is.readLine();
    
    os = new PrintWriter(socket.getOutputStream(), true);
    
    String response = 
     "<html><head></head>" +
     "<body>" +
     "<h1>" + h1 + "</h1>" +
     "</body></html>";
    
    os.print("HTTP/1.0 200" + "\r\n");
    os.print("Content type: text/html" + "\r\n");
    os.print("Content length: " + response.length() + "\r\n");
    os.print("\r\n");
    os.print(response + "\r\n");
    os.flush();
    socket.close();
    
    
    msgLog += "Request of " + request 
      + " from " + socket.getInetAddress().toString() + "\n";
    MainActivity.this.runOnUiThread(new Runnable() {

     @Override
     public void run() {
      
      infoMsg.setText(msgLog);
     }
    });
    
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   
   return;
  }
 }

}

<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" />
    
    <EditText
        android:id="@+id/welcomemsg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Welcome from Android-er" />

    <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>

download filesDownload the files.

Related:
Simple web server using org.apache.http.protocol.HttpService

Updated@2015-11-25:
Permission of "android.permission.INTERNET" is needed in AndroidManifest.xml.

Updated@2015-11-26:
This code NOT work on Android 5, may be all 5+ version.
Fixed, refer post "socket.getInetAddress() return null on Android 5".

7 comments:

rizwan rasheed said...

your blog is best.....
how to share external storage directory and make them downloadable from pc... like wifi file sharing applications

Sukhpal Saini said...

Great Tutorial
Please sir/mam
how to share external storage directory and make them downloadable from pc... like wifi file sharing applications

Prasad Kothavale said...

I guess it will also require internet permission

in AndroidManifest.xml

Anonymous said...

How to send image through socket and user can download from it?

Anonymous said...

this application is not working as shown in the video. I added a few permissions to manifest file but still i don't get logs on the screen. Can anyone help?

Mridul Gupta said...

Dont socket.close() before reading InetAddress.

Andr.oid Eric said...

hello Mridul Gupta,

Yes, I already Updated@2015-11-26:
This code NOT work on Android 5, may be all 5+ version.
Fixed, refer post "socket.getInetAddress() return null on Android 5".