- When the Server run, it will show it's own IP and port, open a ServerSocket and wait for socket connection from clients.
- In Client side, enter message to be sent to server, enter the server Ip and port, then clieck Connect... button, The client will connect to server using socket with DataInputStream and DataOutputStream loaded with message to send.
- In client side, when serverSocket.accept(), it will retrieve the message sent with dataInputStream.readUTF().
Both client and server need permission of "android.permission.INTERNET" in AndroidManifest.xml.
Notice:
- All code for network operation should run in background thread.
- The code dataInputStream.readUTF() will block the program flow if no data input. (Read Pervent program blocked by DataInputStream.readUTF())
Notice:
- All code for network operation should run in background thread.
- The code dataInputStream.readUTF() will block the program flow if no data input. (Read Pervent program blocked by DataInputStream.readUTF())
Example code in Server Side:
package com.example.androidserversocket;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
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() {
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
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 = serverSocket.accept();
dataInputStream = new DataInputStream(
socket.getInputStream());
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
String messageFromClient = "";
//If no message sent from client, this code will block the program
messageFromClient = dataInputStream.readUTF();
count++;
message += "#" + count + " from " + socket.getInetAddress()
+ ":" + socket.getPort() + "\n"
+ "Msg from client: " + messageFromClient + "\n";
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
msg.setText(message);
}
});
String msgReply = "Hello from Android, you are #" + count;
dataOutputStream.writeUTF(msgReply);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
final String errMsg = e.toString();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
msg.setText(errMsg);
}
});
} finally {
if (socket != null) {
try {
socket.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();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
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;
}
}
Layout:
<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>
Download the files.
Example code in Client Side:
package com.example.androidclient;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
TextView textResponse;
EditText editTextAddress, editTextPort;
Button buttonConnect, buttonClear;
EditText welcomeMsg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextAddress = (EditText) findViewById(R.id.address);
editTextPort = (EditText) findViewById(R.id.port);
buttonConnect = (Button) findViewById(R.id.connect);
buttonClear = (Button) findViewById(R.id.clear);
textResponse = (TextView) findViewById(R.id.response);
welcomeMsg = (EditText)findViewById(R.id.welcomemsg);
buttonConnect.setOnClickListener(buttonConnectOnClickListener);
buttonClear.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
textResponse.setText("");
}
});
}
OnClickListener buttonConnectOnClickListener = new OnClickListener() {
@Override
public void onClick(View arg0) {
String tMsg = welcomeMsg.getText().toString();
if(tMsg.equals("")){
tMsg = null;
Toast.makeText(MainActivity.this, "No Welcome Msg sent", Toast.LENGTH_SHORT).show();
}
MyClientTask myClientTask = new MyClientTask(editTextAddress
.getText().toString(), Integer.parseInt(editTextPort
.getText().toString()),
tMsg);
myClientTask.execute();
}
};
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
String msgToServer;
MyClientTask(String addr, int port, String msgTo) {
dstAddress = addr;
dstPort = port;
msgToServer = msgTo;
}
@Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
socket = new Socket(dstAddress, dstPort);
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
if(msgToServer != null){
dataOutputStream.writeUTF(msgToServer);
}
response = dataInputStream.readUTF();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
} 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();
}
}
}
return null;
}
@Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
}
}
Layout:
<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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
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:hint="Say hello to server" />
<EditText
android:id="@+id/address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="dstAddress" />
<EditText
android:id="@+id/port"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="dstPort" />
<Button
android:id="@+id/connect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Connect..."/>
<Button
android:id="@+id/clear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Clear"/>
<TextView
android:id="@+id/response"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Download the files.
Client and Server run on WiFi share hotspot:
The following video, at 1:22, show it work when both client and server connect to the shared WiFi network from server hotspot.
Next:
- Pervent program blocked by DataInputStream.readUTF()
- Editable message sent from server
- Java/JavaFX Client link to Android Server
- Java/JavaFX Client run on Raspberry Pi, link with Android Server
- Java/JavaFX Server link to Android Client
- A Simple Chat App
This is awesome. I love how simple it is. I have two questions however:
ReplyDeleteif I want to send messages from the server to the client as well and have the server receive them would it work if I use the client side of your code into the server part of the code and the server part of your code into the client side of the code?
Also I am thinking of changing it so that when pressing connect a new screen shows up where the client can also view the chat messages from the server and send messages. Will it be possible to do this through intents? Sorry if my questions sound silly. I am new to android programming.
hello blackjwl,
ReplyDelete"send messages from the server to the client" have already been done in the example. The message "Hello from Android, you are #" is sent from server to client after connected.
For "chat" application, I have no idea right now, may be will try later.
Thx
I see, well I am working on that these days and your code seemed pretty much the solution to a chat application as I thought I only need to add a text box to the server app's xml layout and enter text instead of sending a hard coded message. I did not mean a fully fledged chat application only chatting between the server and client taking place in the simplest way possible.
ReplyDeleteAnyway I have tried to run your code on two separate emulators and I do not get the local IP address shown as the "SiteLocalAddress" when I run the server app. I only see one SiteLocalAddress statement mentioning "10.0.2.15"
and when I enter that into the client app on the other emulator I got an IOexception java.net.ConnectException saying failed to connect to 10.0.2.15. Connect failed ECONNREFUSED(connection refused).
After that when I entered my computer's local IP address into the client app's text box thinking maybe it would work even if it doesn't show it but absolutely NOTHING happened. I had copied and pasted your code exactly as it is and had run it. Any idea why I can;t run it like you did in the video?
Add the permissions
Delete(Uses internet,access ntwk state )
I forgot to mention one other thing, when I tried to run the apps again on the two separate emulators, and I put in the local ip address of my computer even though it did not show up on the server app, I decided to wait and see what happens and I ended up getting an error saying failed to connect to 192.168.0.7 ETIMEDOUT(Connection timed out).
ReplyDeleteif I run the server app on the mobile and the client app on the emulator your code works however. I am still trying to make the server send a message from the user to the client through a textbox rather than a hardcoded string message but the application just crashes. I have been at this all day and it is starting to drive me crazy.
ReplyDeleteServerActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
msg.setText(message);
}
});
sendChat.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
chatMsg= chatBoxText.getText().toString();
try {
dataOutputStream.writeUTF(chatMsg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Any clues on how I can insert a textfield that would send the message to the client without causing it to crash?
hello blackjwl,
ReplyDeleteIs it http://android-er.blogspot.com/2014/08/clientserver-example-editable-message.html what you want?
Strongly recommend NOT to test on Emulator.
Thank you so much. :) this tutorial proved to be very useful! :)
ReplyDeleteBut, 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?
Please check:
ReplyDeleteImplement simple Android Chat Application, server side..
and
Simple Android Chat Application, client side.
Is it gonna work if I try to connect on different networks?
ReplyDeleteAwesome....It is really working.Can you please provide a similar code which can transfer files between two android devices
ReplyDeletehello Sauradipta Mishra,
ReplyDeletePlease check File transfer via Socket, between Android devices.
Hi guys,
ReplyDeleteCould anyone give me a Python socket server code (I have a server running Python). Thanks a lot.
Thanx for sharing such code. it's really good example.
ReplyDeleteBut, I have one question. Can we make server devices ip adr. static? with code or with android user interface? We may get rid of entering Ip adr. and port every time.
sure you can make the ip static. But it is not the job in the application.
ReplyDeleteHello,
ReplyDeleteI 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).
I tried sending http handshake message from serverSocket(Android code) to websocket(JavaScript code).
WebSocket in JavaScript received onopen() callback function but it immidaitely recived onclose() callback with reason code 1006.
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?
Or is there any other way to create WebSocket Server in andorid similar to serverSocket and communicate with JavaScript websocket?
Mallikarjun
Hello Mallik,
ReplyDeleteI have no idea right now.
I think serverSocket and webSocket cannot communicate directly.
Please,,,,,I need a way to made two mobiles to be connected. Via WIFI and playTicTacToe on them
ReplyDeletemy android mobile is client only, my wifi module is server , if i connect from client the server should connect and the server sending should be seen in a label. for this how to edit your code. please guide
ReplyDeletehi
ReplyDeletei use eclipse with target 17 and i use 2 emulator android on eclipse when i run the application i have a prbm in client i can't connect to the server i have an exception (connection refused)plz hel me
Hello,,,im just thinking if it is possible to divide the codes on connect button. by creating 2 buttons[connect,send].connect is just simply notify you if its connected, then send is to send a message to the server. can anyone help me?
ReplyDeleteThanks for the tutorial its quite helpful!!!!!
ReplyDeleteHow can I send the location of the server to client on button click.
As expected, Always find a solution from your blog.Thank you
ReplyDeleteHi!
ReplyDeleteis posible to use the same code for ObjectInputStream and ObjectInputStream? Because, i tried but i didnt have any result. Thanks!!
Regards
Hi,
ReplyDeleteI am trying to execute your example, but i always got failed to connect IOException also isConnectedFailed: EHOSTUNREACH(no route to host), Please help to resolve this exception.
I am trying to execute your example, but i always got failed to connect IOException also isConnectedFailed: EHOSTUNREACH(no route to host), Please help to resolve this exception.
ReplyDeleteHi
ReplyDeleteThank you so much for your shared code. It is very useful.
I have question. imagine we have many clients. can server send message to specific client ?
for example We have 192.168.43.228 and 192.168.43.154 as client . can server send message to just 192.168.43.228?
Hello Rasoul Gholamhosseinzadeh,
ReplyDeleteIn this example, the server start ServerSocket and wait request from client. The communication link is initiate by client, then server reply something, than close. So the server cannot initiate communication to client.
But you can check socket.getInetAddress() to determine what to reply.
I only implemented client code since I need to connect to a telnet server.
ReplyDeleteIs this possibile ??
When I press connect I obtain no messages and no errors. Simply, nothing happens !!
i have a same question:
ReplyDeleteRasoul Gholamhosseinzadeh said...
Hi
Thank you so much for your shared code. It is very useful.
I have question. imagine we have many clients. can server send message to specific client ?
for example We have 192.168.43.228 and 192.168.43.154 as client . can server send message to just 192.168.43.228?
anybody have example?help please
Hello Rasoul Gholamhosseinzadeh and Iqra Ali,
ReplyDeleteI think what you want is Android Chat example, with server sending individual message to specify client..
thankyou :)
ReplyDeleteits really helpful
and if i want to communicate with different network. any example about this?
i want to communicate with different network. any example about this?
ReplyDeleteand also i want some modification like a client sends a msg to the server then server forward it to other user.
hey thank you for code. i used your client side code and use another app as server i can send a msg but i can not receive from another server app and also cant see the chat panel which is shown in ur video.
ReplyDeleteHello I want server and client side code is it possible to give me this code my emaild id is kirtigiripunje@gmail.com thanks
ReplyDeletehello kirti kumar,
ReplyDeleteThe post already had links to download the code.
Hello,
ReplyDeleteOn the Client side, I would like to connect to the server, then send multiple messages. At the moment, I am able to connect once and send a message, however, when I click on the "Connect" button again it tries to create a new socket. I want the same connected socket to send multiple messages. Is it possible? Is there another example with this implementation?
Thanks
i want to run this client and server in different network and want them to communicate. how do i do this. how to do port forwarding.
ReplyDeleteon my router wifi its work,phones are connect, when the ip is 10.0.0.2, but in mobile network how can it work? what need to change?
ReplyDeletehello Pavel Palei,
ReplyDeleteAs I know, most mobile network provider block your port as server, not related to the program. So mobile phone can be a client, but not as server.
This comment has been removed by the author.
ReplyDeletewhy we need to create new Socket every time we send massage? the connection stop after thread executed?
ReplyDeleteis there another ways communicate with sockets?
hello Pavel Palei,
ReplyDeleteDepends on your implementation. In this simple example, client side only connect to server, send data, and close.
Refer to another example of A Simple Chat App (listed below "Next:"), connection no close after connected.
i have problem i dont recived data i recevd java.io.EOFException
ReplyDeleteNB:i have a python client and i send the data it is tested
Hi sir,Thank you very much very good tutorial.
ReplyDeleteBut sir , I have one question how to transfer file or bidirectional communication "file" using socket ..please help me .thanks
Sir, how to transfer live camera preview from mobile to mobile using socket
ReplyDeletehow to pass music files through socket
ReplyDelete