Is it possible to connect two phones using socket programming?
I tried following code but it didn't work
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
serverStatus = (TextView) findViewById(R.id.server_status);
SERVERIP = getLocalIpAddress();//Public function to get ip address to it is //working fine
Thread fst = new Thread(new ServerThread());
fst.start();
}
public class ServerThread implements Runnable {
public void run() {
try {
if (SERVERIP != null) {
handler.post(new Runnable() {
public void run() {
serverStatus.setText("Listening on IP: " + SERVERIP);
}
});
serverSocket = new ServerSocket(8087);
} else {
handler.post(new Runnable() {
public void run() {
serverStatus.setText("Couldn't detect internet connection.");
}
});
}
} catch (Exception e) {
handler.post(new Runnable() {
public void run() {
serverStatus.setText("Error");
}
});
e.printStackTrace();
}
}
}
As per socket programming two client socket cannot connect each other. similarly two server socket cannot connect eachother. The code you have written tells that you have written server socket. u need a client socket which will connect to server socket. to create client socket u need ip and port of server socket. Please have a look on the code below. Donot forget to vote if you find the response is useful for you. The below example is in core java. u can implemnet the both in andriod also.
Server
-------
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
class TCPServer
{
public static void main(String argv[]) throws Exception
{
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(6789);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
}
}
}
Client
--------------
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.Socket;
class TCPClient
{
public static void main(String argv[]) throws Exception
{
String sentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER: " + modifiedSentence);
clientSocket.close();
}
}
Thanks
Deepak
Yes, it is possible but I think the first thing you should do is read up on Java Socket programming as there are a few problems with your code that make me think you haven't quite got a grasp of it yet. The main problems are:
Your ServerSocket never accepts a connection and is therefore never actually 'listening'.
Even if it was listening, if this code is running on both phones they would both only be listening and not actively seeking a connection with each-other.
You will need to implement a client on one phone and a server on the other like #Deepak has shown.
Also, you may want to check out AsyncTask in this article for updating views from a non-UI thread (instead of a handler).
Finally, make sure your app includes the android.permission.INTERNET permission in AndroidManifest.xml.
Related
Use case:
NodeMCU connects to Android over TCP socket, then Android plays a sound, when user presses a button, which is connected to NodeMCU.
I couldn't find a way (that I could believe as reliable) to have Android's ServerSocket to notice a reset from NodeMCU client socket, right at once, when NodeMCU's socket is disconnected, or trying to reconnect.
This is my newbee socket code bellow, which I got it working also with the help of this forum. I tried to make it as short as possible when posting here, keeping only relevant parts, but if you need I can just drop all the code, so please let me know in case.
Please suggest me a way. Any other comment to help me understand more of sockets is very welcome.
I'd like to finally learn what sockets are!
public class MainActivity extends AppCompatActivity {
ServerSocket serverSocket;
Thread socketServerThread = null;
protected void onCreate(Bundle savedInstanceState) {
//...
Globals.snd = MediaPlayer.create(this, R.raw.bike_horn);// Globals - static class
//...
socketServerThread = new Thread(new SocketServerThread());
socketServerThread.start();
}
protected void onDestroy() {
if (serverSocket != null) {...//try close it}
}
private class SocketServerThread extends Thread {
//...
static final int SocketServerPORT = 8080;
public void run() {
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
BufferedReader input = null;
try {
serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(SocketServerPORT));
while (true) {
socket = serverSocket.accept();
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
while(socket.isConnected()){
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
message = input.readLine();
if(message == null) break;
int x = Integer.valueOf(message);
if(x == 1) Globals.snd.start();
}
}
}catch (IOException e) {// print error stack
}finally{//close socket, dataInputStream, dataOutputStream
}
NodeMCU code:
#include <ESP8266WiFi.h>
//...variables defined
void setup() {
//...connect to wifi
client.connect(host, port);
}
void loop() {
if(!client.connected()){
if (!client.connect(host, port)) {
return;
}
}
while(digitalRead(beepBtnPin) == LOW && client.connected()){
client.println("2");
client.flush();
delay(500);
}
}
You should put all code after
socket = serverSocket.accept();
In a so called client thread. This is normally done to handle more clients at once.
The server then immediately waits for the next client to connect.
My problem when I try to send a simple "hello world" msg from the pc "client " to the phone "server " and
I tried all possible solution like : starting the server app which is on the phone first then the client but didn't work,
I changed the ip address too but didn't work,
I closed the firewall nothing happened too
Server's code:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);}
public class Server{
public void main(String args[]) {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(5000);} catch (IOException e) {
e.printStackTrace();
}
while (true) {
// Wait for a client connection.
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
// Create and start a thread to handle the new client
try {
// Get the socket's InputStream, to read bytes
// from the socket
InputStream in = clientSocket.getInputStream();
// wrap the InputStream in a reader so you can
// read a String instead of bytes
BufferedReader reader = new BufferedReader(
new InputStreamReader(in, Charset.forName("UTF-8")));
// Read from the socket and print line by line
String line;
while ((line = reader.readLine()) != null) {
Toast.makeText(getApplicationContext(),line,Toast.LENGTH_LONG).show();
}
}
catch (IOException e) {
e.printStackTrace();
} finally {
// This finally block ensures the socket is closed.
// A try-with-resources block cannot be used because
// the socket is passed into a thread, so it isn't
// created and closed in the same block
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}}
Client's code:
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class ClientClass {
public static void main(String args[]) {
try (Socket socket = new Socket("192.168.1.3", 5000);) {
// We'll reach this code once we've connected to the server
// Write a string into the socket, and flush the buffer
OutputStream outStream = socket.getOutputStream();
PrintWriter writer = new PrintWriter(
new OutputStreamWriter(outStream, StandardCharsets.UTF_8));
writer.println("Hello world!");
writer.flush();
} catch (IOException e) {
// Exception should be handled.
e.printStackTrace();
}
}
}
error:
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at ClientClass.main(ClientClass.java:10)
BUILD SUCCESSFUL (total time: 2 seconds)
I was having same error, and i managed to know what causes this error in my case, you have to check two things:
1-Router configuration if you are connected using WiFi because you have to forward your port correctly.(How to Set Up Port Forwarding on a Router, it differs according to router type)
2-If this IP address here is the correct IP address of your mobile or not:
Socket socket = new Socket("192.168.1.3", 5000);
(How To Check Your Android IP Address)
In the MainActivity class, the inner class named Server is never instantiated and the "main" method is neither called too.
Please have a look to this Tutorial post so as to have an example of how to implement a server using sockets with android devices.
I have written a small client server application for android. The client is a Java program running on my PC while my Android phone is a server. I'm facing force close issues in my server program. The server starts pretty good, but when I send a string from my PC client, the android application (server) force closes. It has become really annoying. Please help!
Here is my client program running on my PC:
package javaNetPackage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JOptionPane;
public class javaClient {
/**
* #param args
*/
public static void main(String[] args) throws IOException {
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
String serverIpAddress = "10.81.242.220";
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
echoSocket = new Socket(serverAddr, 4444);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection to server");
System.exit(1);
}
String str = JOptionPane.showInputDialog("Please give number");
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(echoSocket.getOutputStream())),true);
out.println(str);
out.close();
in.close();
echoSocket.close();
}
}
And here is my server code running on Android:
package com.vinit.androidserver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
public class MainActivity extends Activity {
ServerSocket ss = null;
String mClientMsg = "";
Thread myCommsThread = null;
protected static final int MSG_ID = 0x1337;
public static final int SERVERPORT = 4444;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView tv=(TextView)findViewById(R.id.textView1);
tv.setText("Nothing from client yet");
this.myCommsThread = new Thread(new CommsThread());
this.myCommsThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Handler myUpdateHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_ID:
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText(mClientMsg);
break;
default:
break;
}
super.handleMessage(msg);
}
};
class CommsThread implements Runnable {
public void run() {
Socket s = null;
try {
ss = new ServerSocket(SERVERPORT );
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
Message m = new Message();
m.what = MSG_ID;
try {
if (s == null)
s = ss.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
String st = null;
st = input.readLine();
mClientMsg = st;
myUpdateHandler.sendMessage(m);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Permissions:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Update:: Okay, I solved the issue of force close. I deleted the permission tags in manifest.xml and re-typed them. But now, I'm facing a different problem here. The sent string from PC client is not getting displayed in my server TextView (textView1 in layout xml, referred to as tv in server code). Default message in tv is "Nothing from client yet". When I send a string from PC client, default message disappears but sent string is not updated in server TextView (tv).
You should set the received string to your Message object sent in myUpdateHandler.sendMessage(m); instead of your mClientMsg field.
You can create and send the Message object as below:
String st = null;
st = input.readLine();
Message msg = Message.obtain(myUpdateHandler, MSG_ID, st);
msg.sendToTarget();
To get the value in your handler,
case MSG_ID:
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText((String) msg.obj);
break;
I would suggest you use a Bundle object instead of the raw object though. http://developer.android.com/reference/android/os/Message.html#setData(android.os.Bundle)
The reason you ends up with an empty string is because your handler and CommsThread run in different threads and thus not using the same instance of mClientMsg.
i.e. changes in CommsThread to mClientMsg is not visible in your handler.
I have developed a chat application using socket programming having 1 client and 1 server.
I am running 2 projects. 1 for client and 1 for server.
My client app gets installed on the emulator but when I click on the icon, it doesnt run.
There are no errors:
package com.client.chat;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.*;
import android.view.*;
import android.view.View.OnClickListener;
import java.net.*;
import java.io.*;
public class ClientActivity extends Activity{
/** Called when the activity is first created. */
private String serverIpAddress = "10.0.2.2";
private static final int TCP_SERVER_PORT = 6000;
private Button bt;
private Socket s;
private TextView tv;
String error;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// bt=(Button)findViewById(R.id.cbtn);
tv=(TextView)findViewById(R.id.clienttext);
tcpclient();
}
private void tcpclient(){
try{
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
s = new Socket(serverAddr, TCP_SERVER_PORT);
}catch(UnknownHostException e){e.printStackTrace(); error=e.toString();
tv.setText(error);
}catch(IOException e){e.printStackTrace();
error=error.toString();
tv.setText(error);
}
try{
EditText et = (EditText) findViewById(R.id.clientedit);
String str = et.getText().toString();
BufferedWriter out = null;
out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String outMsg=str+System.getProperty("line.separator");
// String outMsg = "TCP connecting to " + TCP_SERVER_PORT + System.getProperty("line.separator");
out.write(str);
out.flush();
Log.i("TcpClient", "sent: " + outMsg);
Log.d("Client", "Client sent message");
}catch(UnknownHostException e){e.printStackTrace();
error=e.toString();
tv.setText(error);
}catch(IOException e){e.printStackTrace();
error=e.toString();
tv.setText(error);
}
//accept server response
BufferedReader in=null;
try{
in= new BufferedReader(new InputStreamReader(s.getInputStream()));
String inMsg = in.readLine() + System.getProperty("line.separator");
Log.i("TcpClient", "received: " + inMsg);
//close connection
s.close();
}catch(UnknownHostException e){error=e.toString();
tv.setText(error);
}catch(IOException e){error=e.toString();
tv.setText(error);
}
finish();
}
}
Please help!
remove the finish() or put a break point on it. I bet its hitting that and exiting.
Also, I don't see a while loop, or a new thread or any mechanism to keep the client alive, the tcpClient() will run to the end, and exit the activity, since you only have one activity, it will exit the app.
Run the tcpClient() in thread and it should work.
Thread t = new Thread(){
#Override
public void run() {
tcpclient();
}
};
t.start();
Running the tcpClient() in a thread should be done, yes. but if you don't wrap the readline() in a while loop with a Thread.Sleep() at the end of the loop, the thread will just run to the finish() and exit. I'm not sure if your activity will exit it may.. you need to keep the thread alive by a loop with a sleep() in it. Just putting it in a thread will do nothing.
in= new BufferedReader(new InputStreamReader(s.getInputStream()));
while(!shutDown){
String inMsg = in.readLine() + System.getProperty("line.separator");
Log.i("TcpClient", "received: " + inMsg);
Thread.Sleep(1000); // sleep one second
}
On Android I tried to implement a simple TCP Listener Thread (or copied it from anywhere). It should simply wait for a Text and then do something. The Text is sent, this part works, but this listener-Thread doesn´t even create the Socket for listening correctly.
Has anyone an Idea, whats wrong or another simple approach for me?
The text is defined b myself and not html. I only found much too complicated http-handlers.
import java.lang.*;
import java.io.*;
import java.net.*;
public class Client implements Runnable {
public static void main(String args[]) {
System.out.print("Listening Thread started\n");
try {
Socket skt = new Socket("localhost", 2999);
BufferedReader in = new BufferedReader(new
InputStreamReader(skt.getInputStream()));
System.out.print("Received string: '");
while (!in.ready()) {}
System.out.println(in.readLine()); // Read one line and output it
System.out.print("'\n");
in.close();
}
catch(Exception e) {
System.out.print("Whoops! It didn't work!\n");
System.err.println(e);
}
}
public Client () {
}
#Override
public void run() {
// TODO Auto-generated method stub
main(null);
}
}
The code you showed is used to create a client socket, not a server socket. see below an example of TCP server socket, taken from SystemBash:
class TCPServer
{
public static void main(String argv[]) throws Exception
{
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(6789);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
}
}
}