I'm trying to establish a simple UDP connection between a client program running on an android emulator and a server, on two different systems. The server side is fine, but the client side keeps crashing. Is it a problem with the emulator? Should i redirect the port to make it work?
CLIENT SIDE (on android emulator):
package com.example.clientrecv;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity
{
public String text;
public int serverport=1234;
public byte[] message=new byte[1000];
public Button b;
public DatagramPacket p;
public DatagramSocket s;
public Toast t;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b=(Button) findViewById(R.id.button1);
try {
p = new DatagramPacket(message,message.length);
s = new DatagramSocket(serverport);
try {
s.receive(p);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
text= new String(message,0,p.getLength());
Log.d("hello","the message:"+text);
s.close();
// TODO Auto-generated method stub
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void showmsg()
{
t=Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG);
t.show();
}
}
SERVER SIDE: (on pc)
import java.io.*;
import java.net.*;
class serversend
{
public static void main(String args[]) throws Exception
{
String strmsg="Server says hello";
int serverport=1234;
int len=strmsg.length();
System.out.println("starting");
byte[] message=strmsg.getBytes();
try{
InetAddress local=InetAddress.getByName("localhost");
DatagramSocket s=new DatagramSocket();
DatagramPacket p=new DatagramPacket(message,len,local,serverport);
System.out.println("Running");
s.send(p);
System.out.println("Sent");
}catch(Exception e)
{
System.out.println("caught");
}
}
}
There are many example available that can help you to communicate between server and client using UDP
to communicate between these two should add the client port on server side
InetAddress local = InetAddress.getByName("192.168.1.102");
here are the Following Link For Client Server Communication Using UDP
LINK UDP1
Link UDP2
Android after 3.0 version doesn't allow you to implement networking operations within the main UI Thread. You must define a new Thread for that... Here is how you can do it:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//here you Set up you parameters and launch the thread (e.g):
this.newThread = new Thread(new mThread());
this.newThread.start();
/* Next you define your newThread's run method in wich all networking
operations must take place*/
class mThread implements Runnable {
public void run() {
// Do all networking tasks you need
}
}
Related
I have java code that sends strings via ip to a python script. The code works perfectly with the emulator but when I successfully install the app via usb to my phone it does not work. Here is the code:
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class MainActivity extends AppCompatActivity {
public String message;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btn_python = findViewById(R.id.python);
final Button btn_movie = findViewById(R.id.movie);
final Button btn_hw = findViewById(R.id.homework);
btn_python.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view1) {
send py = new send();
message = "python";
Log.i("Button", "Button works");
System.out.println("whatever");
py.execute();
}
});
btn_movie.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view2) {
send mov = new send();
message = "movie";
mov.execute();
}
});
btn_hw.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view2) {
send hw = new send();
message = "homework";
hw.execute();
}
});
}
class send extends AsyncTask<Void,Void,Void>{
Socket s;
PrintWriter pw;
#Override
protected Void doInBackground(Void...params) {
System.out.println("whatevernumbertwo");
try {
System.out.println("whatevernumberthree");
s = new Socket("ip address", 7800);
Log.i("Socket", "connects to socket");
pw = new PrintWriter(s.getOutputStream());
Log.i("output stream", "Output stream works");
pw.write(message);
Log.i("write", "Write works");
pw.flush();
Log.i("flush", "Flush works");
pw.close();
s.close();
} catch (UnknownHostException e) {
System.out.println("Fail");
e.printStackTrace();
} catch (IOException e) {
System.out.println("Fail");
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
}
As I mentioned this works on the emulator but not on the actual device. The proper permissions have also been given. What am I doing wrong? Thanks in advance.
After much digging around, it turned out to be the server's firewall all along. That explains why (apparently) no exception was thrown, and why the code didn't seem to execute; it was executing, it was just getting stuck inside Socket() (during the connect).
Surely Socket() is, in fact, throwing an IOException; it probably just takes a while.
The code works on the emulator because, as it is operating on the same machine, it is behind the firewall.
I want to send a UDP message from PC(server) to my android phone 4.2(client) using WIFI connection. My phone and PC are connected via wireless router. But no message is received from phone to mobile.
I have understood from debugging that the program is waiting at socket.receive(packet);. So, there is no update on the UI.
I want to show message to the UI when server received a message from client and this process will be continue.
I would be grateful, if you could help me. Thank you. I have added necessary permission.
server:
package com.example.abuttontest;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import android.app.Activity;
import android.os.Bundle;
import android.provider.Settings.System;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity
{
private TextView tv;
int i =0;
// String s;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1 = (Button) findViewById(R.id.button1);
tv = (TextView) findViewById(R.id.textView1);
//TextView textMessage = (TextView) findViewById(R.id.textView2);
button1.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
/*cheack ping message*/
//boolean morgan= isOnline();
//String s = String.valueOf(morgan);
tv.setText("kkkkkkkkkk"); // print ping message
Log.d("MyTag#","This is sample log message");
}
});
/* Thread for receiving Data from CLient */
runThread();
}
private void runThread()
{
new Thread()
{
public void run()
{
Log.d("p2p", "1");
while (i++ < 1000)
{
Log.d("p2p", "2");
try {
/////////////////////
//System.out.println("aaa");
byte[] inbuf = new byte[1000]; // default size
DatagramPacket packet = new DatagramPacket(inbuf, inbuf.length);
Log.d("p2p", "3");
DatagramSocket socket = new DatagramSocket(6000);
socket.receive(packet);
Log.d("p2p", "4");
int numBytesReceived = packet.getLength();
//System.out.println(numBytesReceived);
String s = new String(inbuf);
//System.out.println(s);
//System.out.println(inbuf[2]);
socket.close();
Log.d("p2p", "5");
runOnUiThread(new Runnable()
{
#Override
public void run()
{
tv.setText("#" + i);
}
});
Thread.sleep(300);
}
catch (InterruptedException e)
{
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.one)
{
Toast.makeText(getApplicationContext(), "Toast Message ONE", Toast.LENGTH_LONG).show();
}
if (id == R.id.two)
{
Toast.makeText(getApplicationContext(), "Toast Message TWO", Toast.LENGTH_LONG).show();
}
if (id == R.id.action_settings)
{
return true;
}
return super.onOptionsItemSelected(item);
}
}
client:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*packets in the IP layer are called the datagrams */
/*After creating a packet, the process of sending or receiving it involves calling the send or receive method of DatagramSocket. More specifically, you create a packet, then you create a socket. After you create the socket, you call the send method of DatagramSocket to send the datagram packet or use the receive method of DatagramSocket to receive a packet. You can also use the same DatagramSocket to send and receive multiple packets, each going to different destinations and coming from different sources.*/
public class client
{
public static void main(String args[])
{
System.out.println("from client");
try{
//InetAddress ipaddress = InetAddress.getByName("localhost");
// InetAddress ipaddress = InetAddress.getByName("192.168.0.103");
// while(true)
// {
InetAddress ipaddress = InetAddress.getByName("192.168.0.102");
int port = 6000;
//byte[] buffer = new byte[1024]; // empty byte array
String msg ="hello goooooooogle"; // send this message to the server
byte [] b_array = msg.getBytes();
//on SERVER side DatagramSocket able to receive packets on 8080 port
DatagramPacket packet = new DatagramPacket(b_array, b_array.length, ipaddress, port);// DatagramPacket(byte[], byte_length, InetAddress, port_number)
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
socket.close();
// }
}
catch(Exception e)
{
System.out.println(e);
}
}
}
In your MainActivity you have not mentioned the port number which your server has to listen on.
i am new by android.I have started work with a simple chat app. I wrote a short code by UDP socket one for client and one for server.Now i have some issues at connectivity android real device which client app installed on it , and emulator device which server app run on it.
Client app is a simple code which must set IP for connection to emulator and also has a EditText for sending a message.(I at this point set 10.0.2.2 or 10.0.2.15. But my app could not send a message from my real device to emulator! What is goes wrong? is needed to more settings?)
Server app has only a textView for getting and showing recived message.
here is Client code:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class ClienttextchatActivity extends Activity
{
private String udpMsg=null;
Handler hand=new Handler();
EditText edtSetIp=null , edtText=null;
Button btnSetIp=null , btnSend=null;
static String ip=null;
static final String LOG_TAG = "UdpStream";
static final int PORT = 8888;
static final int BUF_SIZE=4096;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
edtText=(EditText)findViewById(R.id.edtText);
edtSetIp=(EditText)findViewById(R.id.edtSetIp);
btnSetIp=(Button)findViewById(R.id.btnSetIp);
btnSend=(Button)findViewById(R.id.btnSend);
btnSetIp.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
ip=edtSetIp.getText().toString();
}
});
btnSend.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Thread mythread=new Thread(new th1() );
mythread.start();
}
});
}
//#############################################
public class th1 implements Runnable
{
public void run()
{
udpMsg =edtText.getText().toString();
Log.d(LOG_TAG,udpMsg);
DatagramSocket ds = null;
try
{
ds = new DatagramSocket();
InetAddress serverAddr = InetAddress.getByName(ip);
Log.d(LOG_TAG,"address server address created.");
DatagramPacket dp;
dp = new DatagramPacket(udpMsg.getBytes(), udpMsg.length(), serverAddr, PORT);
ds.send(dp);
Log.d(LOG_TAG,"packet send.");
}
catch (SocketException e)
{
e.printStackTrace();
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (ds != null)
{
ds.close();
}
}
}//end run
}//end class th
}
Make sure emulator is started, then in ADB shell, type this command, it will show ip address of emulator.
adb shell
ifconfig etho
I have Created a Service Which in turn Creates a Socket, But as soon as try to read data sent from Server, it hangs ,On the other hand the same code run if i am not using Service but plain Activity ??
import android.app.*;
import android.content.*;
import android.os.*;
import android.util.*;
import java.net.*;
import java.io.*;
import android.widget.*;
public class BackgroundService extends Service
{
private Socket socket=null;
private InputStreamReader in=null;
private String ip;
private String tag="BackgroundService";
public IBinder onBind(Intent p1)
{
// TODO: Implement this method
return null;
}
public void onCreate(){
super.onCreate();
}
public void onStart(Intent i,int id){
super.onStart(i,id);
ip=i.getStringExtra("Ip");
Log.v(tag,"Ip "+i.getStringExtra("Ip"));
try
{
socket = new Socket(ip.trim(), 8888);
new Runnable() {
public void run()
{
// Hangs in this block.....
try
{
in = new InputStreamReader (socket.getInputStream());
BufferedReader bf=new BufferedReader (in);
// Never Reaches this messge
Log.v(tag,"mess:"+bf.readLine() );
}
catch (IOException e)
{
e.printStackTrace();
}
}
}.run();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Log.v is the Problem it wont allow you print the value so use System.out.println() and bf.printline will contain the message
In my application i want to do bluetooth chat. I'm facing a problem in threading. In my application my android phone will work as server which has a blocking statement
socket=mServerSocket.accept();
for this purpose i've created a child thread so that it will run separately. But before finishing this child thread main thread goes down giving Force Close and if i use the .join() method it hangs up my UI.
What is the solution to run both threads parallel?
this is my code
main Activity
package com.my.bluechat_2_1;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class BlueChat extends Activity {
/** Called when the activity is first created. */
private BlueHandler btHandler=null;
private BluetoothAdapter btAdapter = null;
private Context context=this;
TextView chatWindow=null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
chatWindow=(TextView)findViewById(R.id.textView1);
doStart();
}
private void doStart(){
Button btnStart=(Button)findViewById(R.id.button1);
btnStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// Get local Bluetooth adapter
btAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if(btAdapter == null)
{
Toast.makeText(context, "Device does not support Bluetooth", Toast.LENGTH_LONG).show();
}
if (!btAdapter.isEnabled()) {
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
chatWindow.append("Waiting for connection...\n");
btHandler=new BlueHandler(context,chatWindow,btAdapter);
Thread acceptThread=new Thread(btHandler);
acceptThread.start();
}
});
}
}
BlueHandler
package com.my.bluechat_2_1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.widget.TextView;
import android.widget.Toast;
public class BlueHandler implements Runnable{
// Name for the SDP record when creating server socket
private static final String SMARTCAM_BT_SERVICE_NAME = "SmartCam";
// Unique UUID for this application
private static final UUID SMARTCAM_BT_SERVICE_UUID = UUID.fromString("95b82690-4c94-11e1-b86c-0800200c9a66");
private BluetoothAdapter btAdapter = null;
private BluetoothServerSocket btServerSocket = null;
private BluetoothSocket btSocket = null;
private InputStream btInputStream=null;
private Context contextObj=null;
private TextView textView;
public BlueHandler(Context contextObj,TextView textView,BluetoothAdapter btAdapter){
this.contextObj=contextObj;
this.btAdapter=btAdapter;
this.textView=textView;
try {
btServerSocket=this.btAdapter.listenUsingRfcommWithServiceRecord(SMARTCAM_BT_SERVICE_NAME, SMARTCAM_BT_SERVICE_UUID);
} catch (IOException e) {
// TODO Auto-generated catch block
Toast.makeText(this.contextObj, "Service not created", Toast.LENGTH_LONG);
}
}
#Override
public void run() {
// TODO Auto-generated method stub
textView.append("Inside child thread.\n");
textView.append(btServerSocket+"\n");
while (true) {
try {
btSocket = btServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (btSocket != null) {
// Do work to manage the connection (in a separate thread)
try {
btServerSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
textView.append("Connected.\n");
try {
btInputStream=btSocket.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] buffer = new byte[1024]; // buffer store for the stream
String s;
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes=btInputStream.read(buffer);
s= new String(buffer);
// Send the obtained bytes to the UI Activity
textView.append("received ::" +s+"\n");
} catch (IOException e) {
break;
}
}
}
}
You're probably getting a crash because you're accessing a textView on the worker thread. You'll need to use TextView.post(Runnable) to make that not happen.
In reality you should be using a bindable Service to do this kind of work. You can post back to the UI via broadcast intents or callback methods, That way you don't have to worry about rotation bugs.
Are you performing a long operation in the constructor of your children thread? Each long operation must be done in the run() method.