Android sends UDP packets to a Java client over WiFi - java

I'm creating 2 programs which one of them sends UDP packets from an Adnroid device and a second one (Java) receives them. So it works good if I use WiFi-router. But if I use a direct connection the Java application doesn't receive these packets. Under the direct connection I mean creating HOTSPOT on computer and connecting to it by the Android device. I used code snippet bellow:
Server's code:
public class UDPServer {
InetAddress groupAddress;
DatagramPacket packet;
byte[] buffer;
DatagramSocket socket;
static String ip = "227.0.25.57";
static int port = 6789;
private boolean isRun = false;
private String message = "";
private int broadcastInterval;
public void StopBroadcasting(){
isRun = false;
}
public void StartBroadcasting(String message, int broadcastInterval){
isRun = true;
this.message = message;
this.broadcastInterval = broadcastInterval;
new Thread(runner).start();
}
Runnable runner = new Runnable() {
#Override
public void run() {
while(isRun){
try {
SendBroadcastMessage(message);
System.out.println("msg sended...");
Thread.sleep(broadcastInterval);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("Stopping UDPServer...");
}
};
public UDPServer() {
buffer = new byte[4096];
try {
groupAddress = InetAddress.getByName(ip);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
socket = new DatagramSocket();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void SendBroadcastMessage(String msg) throws IOException{
if(msg==null) return;
buffer = msg.getBytes();
packet = new //DatagramPacket(buffer, buffer.length);
DatagramPacket(buffer, buffer.length, groupAddress, port);
socket.send(packet);
}
public static void Send(String msg){
try {
InetAddress group = InetAddress.getByName(ip);
MulticastSocket s = new MulticastSocket(port);
s.joinGroup(group);
DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),
group, port);
s.send(hi);
System.out.println("send...");
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}
Client's code:
public class UDPClient {}
MulticastSocket socket;
InetAddress groupAddress;
DatagramPacket packet;
byte[] buffer;
static String ip = "227.0.25.57";
static int port = 6789;
public interface OnReceiveDataListener{
public abstract void onReceiveData(String data);
}
private OnReceiveDataListener ReceiveDataListener = null;
public void setReceiveDataListener(OnReceiveDataListener ReceiveDataListener) {
this.ReceiveDataListener = ReceiveDataListener;
}
public OnReceiveDataListener getReceiveDataListener() {
return ReceiveDataListener;
}
private boolean isRun = false;
private Thread broadcastReceiver;
public void StopBroadcasting(){
isRun = false;
if(broadcastReceiver!=null)
broadcastReceiver.interrupt();
}
public void StartBroadcasting(){
isRun = true;
broadcastReceiver = new Thread(runner);
broadcastReceiver.start();
}
Runnable runner = new Runnable() {
#Override
public void run() {
while(isRun){
try {
String msg = ReceiveBroadcastMessage();
if(ReceiveDataListener!=null)
ReceiveDataListener.onReceiveData(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
public UDPClient(){
buffer = new byte[4096];
try {
groupAddress = InetAddress.getByName(ip);
socket = new MulticastSocket(port);
socket.joinGroup(groupAddress);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public String ReceiveBroadcastMessage() throws IOException{
packet = new DatagramPacket(buffer, buffer.length);
System.out.println("before receive");
socket.receive(packet);
System.out.println(packet.getData());
return new String(packet.getData());
}
public void DeInit(){
try {
socket.leaveGroup(groupAddress);
} catch (IOException e) {
e.printStackTrace();
}
socket.close();
}
MulticastSocket msocket;
public static void Receive(){
MulticastSocket msocket;
try {
msocket = new MulticastSocket(port);
InetAddress group = InetAddress.getByName(ip);
msocket.joinGroup(group);
byte[] inbuf = new byte[1024];
DatagramPacket packet = new DatagramPacket(inbuf, inbuf.length);
System.out.println("before receive");
msocket.receive(packet);
System.out.println("after receive");
int numBytesReceived = packet.getLength();
System.out.println(new String(packet.getData()));
msocket.leaveGroup(group);
msocket.close();
System.out.println(numBytesReceived);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}
If you could see I have 2 methods of sending and receiving packets. The both don't work! What do I wrong?
Help me please.

I've found solution:
http://code.google.com/p/boxeeremote/wiki/AndroidUDP

Related

a echo server which handle clients with pool of thread

client connection works (I use telnet), but nothing happens when I write a message with any client - even the condition with empty char (for disconnection).
I don't understand why. I get capacity and port with args[], and I start the server.
I already tested a simpler version with just a server which can handle one by one client, and it works.
public class EchoClient extends Thread {
EchoServerForPool serv;
BufferedReader inchan;
DataOutputStream outchan;
Socket socket;
int port;
public EchoClient(EchoServerForPool serv) {
// TODO Auto-generated constructor stub
this.serv = serv;
}
#Override
public void run() {
// TODO Auto-generated method stub
Socket s;
while (true) {
synchronized (this.serv) {
if (this.serv.stillWaiting() == 0) {
try {
this.serv.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
s = this.serv.removeFirstSocket();
serv.newConnect();
}
try {
inchan = new BufferedReader(new InputStreamReader(s.getInputStream()));
outchan = new DataOutputStream(s.getOutputStream());
String message = inchan.readLine();
if (message.equals("")) {
System.out.println("fin de connection");
break;
}
outchan.writeChars(message + "\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
s.close();
synchronized (serv) {
serv.clientLeft();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class EchoServerForPool extends Thread {
ArrayList<EchoClient> clients;
ArrayList<Socket> sockets;
Socket client;
int nbLocalhost = 0;
int capacity, port, nbConnectedClient, nbWaitingSocket;
public EchoServerForPool(int capacity, int port) {
// TODO Auto-generated constructor stub
this.capacity = capacity;
this.port = port;
clients = new ArrayList<EchoClient>(capacity);
sockets = new ArrayList<Socket>();
for (int i = 0; i < clients.size(); i++) {
EchoClient ec_i = new EchoClient(this);
clients.add(ec_i);
ec_i.start();
}
}
public Socket removeFirstSocket() {
Socket res = sockets.get(0);
sockets.remove(0);
return res;
}
public void newConnect() {
nbConnectedClient++;
nbWaitingSocket--;
}
public int stillWaiting() {
return nbWaitingSocket;
}
public void clientLeft() {
nbConnectedClient--;
}
#Override
public void run() {
// TODO Auto-generated method stub
try {
ServerSocket serv = new ServerSocket(this.port);
while (true) {
this.client = serv.accept();
synchronized (this) {
nbLocalhost++;
System.out.println(client.getInetAddress().getHostName() + "-" + nbLocalhost + " connected");
sockets.add(client);
nbWaitingSocket++;
notify();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class EchoPoolThread {
public static void main(String[] args) {
int port = Integer.parseInt(args[0]);
int capacity = Integer.parseInt(args[1]);
EchoClient.EchoServerForPool serveur = new EchoClient.EchoServerForPool(capacity, port);
System.out.println("start server");
serveur.start();
}
}
EDIT : the problem was I iterate with clients.size() which is 0 instead of capacity, for fill my clients list....
I've refactored your code a little bit to have a working solution. You can work from there to create a pool, right now the number of clients isn't limited.
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* #author Gianlu
*/
public class Main {
public static void main(String[] args) {
int port = Integer.parseInt(args[0]);
int capacity = Integer.parseInt(args[1]);
EchoServerForPool serveur = new EchoServerForPool(capacity, port);
System.out.println("start server");
serveur.start();
}
public static class EchoServerForPool extends Thread {
private final int port;
private final ExecutorService executor;
private final ArrayList<EchoClient> clients;
private int nbLocalhost = 0;
public EchoServerForPool(int capacity, int port) {
this.port = port;
clients = new ArrayList<>();
executor = Executors.newFixedThreadPool(capacity);
}
#Override
public void run() {
try {
ServerSocket serv = new ServerSocket(this.port);
while (true) {
Socket socket = serv.accept();
EchoClient client = new EchoClient(this, socket);
executor.submit(client);
clients.add(client);
nbLocalhost++;
System.out.println(socket.getInetAddress().getHostName() + "-" + nbLocalhost + " connected");
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void terminated(EchoClient client) {
clients.remove(client);
}
}
public static class EchoClient implements Runnable {
private final EchoServerForPool pool;
private final Socket socket;
private final BufferedReader inchan;
private final DataOutputStream outchan;
public EchoClient(EchoServerForPool pool, Socket socket) throws IOException {
this.pool = pool;
this.socket = socket;
this.inchan = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.outchan = new DataOutputStream(socket.getOutputStream());
}
#Override
public void run() {
try {
while (true) {
String message = inchan.readLine();
if (message.equals("")) {
System.out.println("fin de connection");
break;
}
outchan.writeChars(message + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
pool.terminated(this);
}
}
}

android.os.NetworkOnMainThreadException but my class extends Thread

I have a client class that extends Thread to start socket programming
my class code
class MyClientMessages extends Thread {
Socket socket;
int PORT = 5002;
DataInputStream din;
DataOutputStream dout;
public MyClientMessages(String IP) {
try {
System.out.println("IP = ======= " + IP + " TYPE = " + TYPE);
//*********** crash here ***************
socket = new Socket(IP,PORT); // *********** it crash here *************
din = new DataInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
this.start();
}catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
while (true) {
byte[] data = new byte[1024];
int size = 0;
try {
while ((size = din.read(data)) > 0) {
final String str = new String(data,"UTF8");
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView textView = new TextView(ServerChat.this);
textView.setTextSize(15);
textView.setText(str);
linearLayout.addView(textView);
}
});
}
}catch (IOException e) {
e.printStackTrace();
try {
dout.close();
din.close();
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
public void WriteToSocket(byte[] arr,int size) {
try {
dout.write(arr,0,size);
dout.flush();
}catch (IOException e) {
e.printStackTrace();
try {
dout.close();
din.close();
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
I make this class inside my activity class. I have another class inside my activity class for server, which extends thread and it works fine. Why does this client class crash and give me this error ?
this how I use it on my onCreate() function:
if (TYPE == 1) {
serverMessages = new MyServerMessages(5002);
Toast.makeText(this,"Room Started Wait clients To Join",Toast.LENGTH_LONG).show();
}
else {
clientMessages = new MyClientMessages(deConvert(mycode)); // crash here
Toast.makeText(this,"Connect To Room",Toast.LENGTH_LONG).show();
}
why this client class crash and give me this error ?
Because you are creating a Socket and opening it in the constructor. Move that logic into run().

Java Send custom object via socket Client, Server, LAN

I want to send object (custom class) via socket from Client to Server. This is my code:
Server:
private class SocketServerThread extends Thread {
#Override
public void run() {
try {
serverSocket = new ServerSocket(socketServerPORT);
while (true) {
clientSocket = serverSocket.accept();
ObjectInputStream inObject = new ObjectInputStream(
clientSocket.getInputStream());
try {
Te xxx = (Te) inObject.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//DataInputStream dataInputStream = new DataInputStream(
//clientSocket.getInputStream());
//messageFromClient=dataInputStream.readUTF();
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
//activity.msgFromC.setText(messageFromClient);
}
});
}
}
Client:
public Client(String aIPaddres, int aPort, Te u) {
AddressIP = aIPaddres;
Port = aPort;
sendUser = u;
}
protected Void doInBackground(Void... arg0) {
Socket clientSocket = null;
try {
clientSocket = new Socket(AddressIP, Port);
ObjectOutputStream outObject = new ObjectOutputStream(
clientSocket.getOutputStream());
outObject.writeObject(sendUser);
//DataOutputStream daneWyjsciowe = new DataOutputStream(
//clientSocket.getOutputStream());
//daneWyjsciowe.writeUTF("Czesc!" );
} 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 (clientSocket != null) {
try {
clientSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
Custom class (Te.class):
public class Te implements Serializable {
public String message;
public Te(String m){
message=m;
}
}
When I passing simple data i.e. String there is no problem. But now I want to pass object, but there is always ClassNotFoundException at server. I read lot of stacks but I didnt find answer. Could U help me?

is.readUTF() not recieving message

For the chat program in android side I am sending message via DataInput stream as
Socket sck = new Socket();
sck.connect(new InetAddress("192.168.1.91",1500),2000);
if(sck.isConnected())
{
DataOutputStream os = new DataOutputStream(sck.getOutputStream());
os.writeUTf(msg);
System.out.println("Message sent");
}
and on the Server side My code is
ServerSocket serv = new ServerSocket(1500);
Socket sock = serv.accept();
DataInputStream is = new DataInputStream(sock.getInputStream);
String ans = is.readUTF();
System.out.println("Got"+ans);
But on server side it seems it does not received anything and still waiting for the message. But on client side It shows message sent.
Here is my full code.
package in.prasilabs.eagleeye;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class EagleClient extends Thread
{
public int ret = 0;
private String ip;
private int port;
private Socket sck;
private boolean estb = false;
private DataInputStream is;
private DataOutputStream os;
private String rmsg = null;
private String msg;
private String username;
private String password;
public String reply;
Data dt = new Data();
public EagleClient()
{
}
public EagleClient(String ip, int port, String username, String password)
{
this.ip = ip;
this.port = port;
this.username = username;
this.password = password;
}
public void run()
{
establish();
if(estb == true)
{
sendInfo(username,password);
}
}
public void establish()
{
int time_out = 2000;
try
{
System.out.println("trying to connect");
sck = new Socket();
sck.connect(new InetSocketAddress(dt.getIp(),dt.getServerPort()),time_out);
estb = true;
System.out.println("Established");
}
catch (UnknownHostException e)
{
ret =0;
e.printStackTrace();
}
catch (IOException e)
{
ret = 0;
// TODO Auto-generated catch block
e.printStackTrace();
}
if(estb == true)
{
try {
is = new DataInputStream(sck.getInputStream());
os = new DataOutputStream(sck.getOutputStream());
dt.setOS(os);
dt.setIS(is);
System.out.println("Messages are ready to send");
} catch (IOException e)
{
ret = 0;
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void sendInfo(String user,String password)
{
Data dt = new Data();
is = dt.getIS();
os = dt.getOS();
String drport = Integer.toString(dt.getdrPort());
try {
os.writeUTF("logn");
System.out.println("Sending user info");
os.writeUTF(dt.getUsername());
os.writeUTF(dt.getPassword());
os.writeUTF(drport);
reply = is.readUTF();
if(reply.equals("success"))
dt.setLoginStatus(true);
else
dt.setLoginStatus(false);
System.out.println("ACk recieved");
} catch (IOException e) {
ret = 0;
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public int sendMessage(String msg)
{
Data dt = new Data();
os = dt.getOS();
is = dt.getIS();
this.msg = msg;
try {
os.writeUTF(msg);
System.out.println("Client :" +msg);
recieveMessage();
} catch (IOException e) {
ret = 0;
// TODO Auto-generated catch block
e.printStackTrace();
}
return ret;
}
public void recieveMessage()
{
try {
System.out.println("Trying to get acknowledgement");
sck.setSoTimeout(2000);
rmsg = is.readUTF();
if(rmsg.equals(msg))
{
System.out.println("Ack recvd" +rmsg);
ret = 1;
}
else if(!msg.equalsIgnoreCase(rmsg))
{
//sendMessage();
Thread.sleep(100);
System.out.println("Retrying");
rmsg = is.readUTF();
System.out.println("Ack recvd" +rmsg);
ret = 1;
}
else
{
System.out.println("Message not recieved");
ret = 0;
}
} catch (IOException e) {
ret = 0;
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
Try to use something like this:
String message = "";
while (!"end".equals(message)) {
if (is.available() != 0) {
message = dis.readUTF();
System.out.println(message);
}
}
I checked this - working. Server must be up before client will send message.

Android, how to obtain correct UDP address

I have got a multicastsocket working on my android phone, I'm trying to connect one to another, one device is hosting as a wifi hotpot, and the other client will just connect, how do I find out the port that the client needs to listen to, to receive packets?
Here is my server code
public class gameServer extends Thread{
/**
* Sets up a server for Android applciation
*/
//Variables
private static final String TAG = "gameServer";
private int port = 50000;
private MulticastSocket socket = null;
private InetAddress address = null;
private ArrayList<gameObject> assets = new ArrayList();
//Client
private DatagramPacket packet;
public gameServer() throws IOException
{
//Setup server
try
{
socket = new MulticastSocket( port );
Log.d(TAG, "Server started");
}
catch ( IOException e)
{
Log.d(TAG, "Error code 0004");
e.printStackTrace();
}
}
public void passClient( gameObject clientTemp )
{
assets.add( clientTemp );
}
#Override
public void run()
{
InetAddress temper = socket.getInetAddress();
Log.d(TAG, "Server thread was started");
System.out.println(temper);
try {
address = InetAddress.getByName("230.0.0.1");
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
socket.joinGroup(address);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while( true )
{
//Send out data
try {
//Setup the data to send to clients
byte[] buf = new byte[256];
String dataToBeSent = "";
for(int i = 0;i < assets.size(); i++)
{
dataToBeSent += assets.get(i).returnPosX() + ":" + assets.get(i).returnPosY();
}
buf = dataToBeSent.getBytes();
// send it
InetAddress group = InetAddress.getByName("230.0.0.1");
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, port);
socket.send(packet);
}
catch (IOException e)
{
e.printStackTrace();
}
//Receive data
byte[] buf = new byte[256];
//Set the properties of the packet (DatagramPacket)
packet = new DatagramPacket(buf, buf.length);
//Receive the data
try {
socket.receive(packet);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Conver the data to a string
String received = new String(packet.getData(), 0, packet.getLength());
//Debug
//Log.d(TAG, received);
}
}
}
Client code
public class gameClient extends Thread {
private static final String TAG = "gameClient";
private gameObject player;
private Context context;
private int port = 50000;
private MulticastSocket socket;
private InetAddress address = null;
private DatagramPacket packet = null;
public gameClient( gameObject temp )
{
player = temp;
try {
socket = new MulticastSocket( port );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public gameObject rtnObj()
{
return player;
}
#Override
public void run()
{
//Gather ip address
try {
address = InetAddress.getByName("192.168.1.1");
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
socket.joinGroup(address);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while( true )
{
//Send out data
try {
//Receive data
byte[] buf = new byte[256];
//Set the properties of the packet (DatagramPacket)
packet = new DatagramPacket(buf, buf.length);
//Receive the data
try {
socket.receive(packet);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Conver the data to a string
String received = new String(packet.getData(), 0, packet.getLength());
String[] posValues = received.split(":");
player.setPosition(Integer.parseInt(posValues[0]), Integer.parseInt(posValues[1]));
//Debug
Log.d(TAG, received);
}
finally
{
}
}
}
}

Categories