Android Client-Server Using Sockets – Server Implementation

In this Android Client-Server Using Sockets post series we will be focusing on server side implementation. We have covered Client side implementation in our previous post “Android Client-Server Using Sockets – Client Implementation” Android has very vast set of libraries so that users can implement innovative ideas with provided libraries. It is very easy to create server in android using these inbuilt library.

Implementation Details

In this tutorial we will be using java Sockets to achieve our server-client communication. One side there will be a server which will bind to specified port on device and will be available to client using IP address and port combination. Client will also use some random port for connection. Once connection is established from client side then server will replay to client with “Hello from Server, you are #%d” %d will be a number which will increment with each connection.

 

[su_button url=”https://github.com/androidsrc/SocketServer” target=”blank” style=”stroked” background=”#51d461″ color=”#ffffff” size=”6″ center=”yes” radius=”0″ icon=”icon: arrow-circle-o-down”]Download Complete Source Code[/su_button]

 

Note : This tutorial is based on Android Studio 2.2, Java 1.6 and Android 6.0.

Server Implementation

Implementing Server.java

This class contain all the implementation of server. In this class we will create object of “ServerSocket” in a separate thread. accept() function in ServerSocket waits for an incoming request and blocks until the connection is opened. This method returns a socket object representing the just opened connection. IP address and port number of client can be obtained from this socket.

private class SocketServerThread extends Thread {

	int count = 0;

	@Override
	public void run() {
		try {
			// create ServerSocket using specified port
			serverSocket = new ServerSocket(socketServerPORT);

			while (true) {
				// block the call until connection is created and return
				// Socket object
				Socket socket = serverSocket.accept();
				count++;
				message += "#" + count + " from "
						+ socket.getInetAddress() + ":"
						+ socket.getPort() + "\n";

				activity.runOnUiThread(new Runnable() {
					@Override
					public void run() {
						activity.msg.setText(message);
					}
				});

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

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

Next we will create object of  “SocketServerReplyThread” which extends thread and we pass socket and count to the constructor. Next obtain OutputStream from Socket using getOutputStream() function. A PrintStream is now created using OutputStream object as the new print stream does not automatically flush its contents to the target stream when a newline is encountered. After that we print() replay on PrintStream and Stream is closed. Huhh so much of theory.

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 Server, you are #" + cnt;

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

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

			activity.runOnUiThread(new Runnable() {

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

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

		activity.runOnUiThread(new Runnable() {

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

At last we will need a method to get IP address of our server.

public 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 += "Server running at : "
							+ inetAddress.getHostAddress();
				}
			}
		}

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

Full implementation of Server.java class

package com.androidsrc.server;

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;

public class Server {
	MainActivity activity;
	ServerSocket serverSocket;
	String message = "";
	static final int socketServerPORT = 8080;

	public Server(MainActivity activity) {
		this.activity = activity;
		Thread socketServerThread = new Thread(new SocketServerThread());
		socketServerThread.start();
	}

	public int getPort() {
		return socketServerPORT;
	}

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

	private class SocketServerThread extends Thread {

		int count = 0;

		@Override
		public void run() {
			try {
				// create ServerSocket using specified port
				serverSocket = new ServerSocket(socketServerPORT);

				while (true) {
					// block the call until connection is created and return
					// Socket object
					Socket socket = serverSocket.accept();
					count++;
					message += "#" + count + " from "
							+ socket.getInetAddress() + ":"
							+ socket.getPort() + "\n";

					activity.runOnUiThread(new Runnable() {
						@Override
						public void run() {
							activity.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 Server, you are #" + cnt;

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

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

				activity.runOnUiThread(new Runnable() {

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

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

			activity.runOnUiThread(new Runnable() {

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

	}

	public 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 += "Server running at : "
								+ inetAddress.getHostAddress();
					}
				}
			}

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

Implementation of MainActivity.java class

The usage of server class is very simple. Just create a object of Server class and pass MainActivity instance in constructor and you are done. Here is what MainActivity.java looks like.

package com.androidsrc.server;

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

public class MainActivity extends Activity {

	Server server;
	TextView infoip, msg;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		infoip = (TextView) findViewById(R.id.infoip);
		msg = (TextView) findViewById(R.id.msg);
		server = new Server(this);
		infoip.setText(server.getIpAddress() + ":" + server.getPort());
	}

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

Other supporting components

Implementation of activity_main.xml file.

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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginBottom="20dp"
        android:layout_marginTop="20dp"
        android:autoLink="web"
        android:text="http://androidsrc.net/"
        android:textStyle="bold"/>

    <TextView
        android:id="@+id/infoip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" />

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

 AndroidManifest.xml

We will need permission INTERNET to create Sockets. Don’t forget to include that permission in your manifest.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.androidsrc.server"
          android:versionCode="1"
          android:versionName="1.0">

    <uses-sdk
        android:minSdkVersion="19"
        android:targetSdkVersion="19"/>

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">

            <intent-filter>

                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest><br>

Testing the application

To test this application install it on android device and install client on other device. Both device should be connected to same wifi network. Now just add IP address and port to client and click connect. Server will replay with a message to client. Thanks

Any further queries or custom tutorial please comment or mail us at androidsrcdotnet@gmail.com

GuRu

Technology enthusiast. Loves to tinker with things. Always trying to create something wonderful using technology. Loves coding for Android, Raspberry pi, Arduino , Opencv and much more.

You may also like...

16 Responses

  1. cie says:

    thank you 🙂

  2. Cyber says:

    I need a quick solution, I have a p2p communication with a device on 4000 port. I need to write a server to receive the messages from this device, since it’s not broadcasting, but gives feedback on a designated ip address. However the result from this app I receive is more like
    “#322 from 192:168.1.6:28617” <- true this is the ip of the application. But I need the response from the device.

    obviously I don't really understand much about socket servers, additionally I need to run this multithreading with other client sockets I wrote and running. But I have a very limited time.

    Can you explain me how can i see the message from this ip?

    • Cyber says:

      Well it turns out I just need to get the data with datainputstream. Thank you for the tutorial! It was really helpful

  3. Abhinav Bhargav says:

    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 asap

  4. David Audrain says:

    SocketServerThread.run should call SocketServerReplyThread.start and not SocketServerReplyThread.run.

  5. Man>Daan says:

    why both should be on same wifi network ? Can we not use external/public ip ?

  6. waysi89 says:

    Thank you, helped me a lot!

  7. Muhammad Ikhsan says:

    The activity_main.xml source code on the article is wrong, it is for http://androidsrc.net/android-web-crawler-example-multithreaded-implementation/. Check the one in the complete source code, for the correct one (https://github.com/androidsrc/SocketServer/blob/master/app/src/main/res/layout/activity_main.xml).

  8. nikhil sani says:

    could you please tell me a method to transfer the data between two clients through server

  9. Yasmine Hamdani says:

    Hello, thank you for the tuto. I’m new to implementing server on android and I would like to know if your code can handle more than one client?
    I mean, the while(true) loop makes it so that each client would have his own socket? Socket that is closed at the end of that loop?
    What happens if two users send a request at the same time?

  10. Thiago says:

    Hello my friend! Thank for your post. I have a question…its possible print the received message on TextView? I can’t do this…Thanks (and sorry my English)!!!!

  11. Salimb53 says:

    Ciao everybody, thank you for your post, i’m using it perfectly but i want to now if it’s possible to the server to replay pictures or videos (not only text !). Merci.

  1. July 1, 2015

    […] Android Client-Server Using Sockets – Server Imple […]

  2. January 30, 2017

    […] Download Complete Source Code[/su_button]In this Android Client-Server Using Sockets post we will be focusing on client side implementation. We have covered Server side implementation in our previous post “Android Client-Server Using Sockets – Server Implementation” […]

  3. December 14, 2018

    […] Android Client-Server Using Sockets – Server Implementation […]

Leave a Reply

Your email address will not be published. Required fields are marked *