Receive on UDP socket and send reply - android

I am working on a client/server project, the client being Android and the server being C#.
What I am trying to do is the Android app listens on a UDP socket and the C# server sends a message on that port. Android will then receive the message from the reply, and send back a response.
This is the code I have:
public void run()
{
Log.d(TAG, "Heartbeat manager thread starting");
try
{
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
DatagramSocket socket = new DatagramSocket(HEARTBEAT_PORT);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (!cancelThread)
{
socket.receive(packet);
final String xml = new String(packet.getData(), 0, packet.getLength());
Log.v(TAG, xml);
XmlSettings xmlSettings = new XmlSettings();
xmlSettings.setIndent(true);
XmlWriter writer = new XmlWriter(xmlSettings);
writer.writeStartDocument();
writer.writeStartElement("HeartbeatManager");
writer.writeElementString("Command", Defines.ServerCommands.HeartbeatResponse.toString());
writer.writeEndElement();
buffer = writer.returnXmlOutput().getBytes();
DatagramPacket replyPacket = new DatagramPacket(buffer, buffer.length);
socket.send(replyPacket);
}
}
catch (SocketException ex)
{
Log.e(TAG, "Socket Exception Occurred: " + ex.toString());
}
catch (IOException ex)
{
Log.e(TAG, "IOException Occurred: " + ex.toString());
}
At the moment it throws an exception when I do the socket.send stating that the destination address is null.

You must set the destination address in the DatagramPacket before sending it.
The constructor you're using (without the address) is just for receiving, not for sending.
In UDP protocol, destination is set in the packet because there is not a connection (like TCP)
So in your code you are telling the socket, which has no concecpt of destination to send a packet without destination, so it'll throw and exception.
InetSocketAddress address = InetSocketAddress("www.google.com", 8080);
DatagramPacket replyPacket = new DatagramPacket(buffer, buffer.length, address);
socket.send(replyPacket);

Related

Android: Send serialized objects interspersed with parameters to server

Situation: : I must either send a parameter to the server, or a serialized object. It can be in any random order.
What I've done: As per this post, I developed a protocol to let the server know what I'm sending just before I actually send it. If its any string, it just goes via PrintWriter.println().
But just before sending a serialized object via ObjectInputStream, I send a PrintWriter.println("O"). So the server knows it must expect a serialized object next.
Problem: I'm getting the StreamCorruptedException, even though I'm using only one instance of ObjectInputStream at the client throughout the socket's life. Should anything be done at the Server end ?
----------------------- EDITED BELOW ---------------------
Client End:
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(thisSocket.getOutputStream())),
true);
if (!sent){
out.println("Dummy");
sent = true;
}
objectOutputStream.flush();
objectOutputStream.reset();
out.println("#SerialO#"); //This param signals the server
//that an object will be sent next.
if(((calcSum) this.obj).getRemotable()){
/*objectOutputStream.flush();
objectOutputStream.reset();*/
Log.i("ENDPOINT", "Sending Serialized data ...");
objectOutputStream.writeObject(this.obj);
objectOutputStream.flush();
objectOutputStream.reset();
// Get the byte array
byte[] byteArray = byteArrayOutputStream.toByteArray();
}
Server End:
while (!Thread.currentThread().isInterrupted()) {
try{
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
// NOW DECLARED AND USED IN UpdateUIThread
//PrintStream out = new PrintStream(socket.getOutputStream());
if(!sent)
{
flg = this.input.readLine().toString();
Log.i("SERVER","SERVER Received False flg as "+flg);
sent = true;
}
else{
flg = this.input.readLine().toString();
System.out.println("SERVER Received flg as "+flg);
if(flg.contains("#SerialO#")){ //Be prepared to
// receive a serilized obj from client
//Log.d("SERVER","Received an object");
CommunicationThread commThread = new CommunicationThread(this.clientSocket,it);
new Thread(commThread).start();
}
else
{
//Log.d("SERVER","Received a parameter "+flg);
executor = Executors.newFixedThreadPool(5);
executor.execute(new updateUIThread(this.clientSocket,flg));
}
}
} catch (IOException e) {
e.printStackTrace();
Log.e("SERVER", "Creation went bad -- "+e.toString());
break;
}
catch (Exception e)
{
Log.d("CLIENT TAG", "Creation went bad -- "+e.toString());
}
}
}
...
public CommunicationThread(Socket clientSocket, Intent it) {
this.clientSocket = clientSocket;
try {
Log.d("SERVER","Inside Server's Comm Thread");
if (mInput==null){
Log.i("SERVER","Receiving very first serialized obj");
mOutput = new ObjectOutputStream(this.clientSocket.getOutputStream());
System.out.println("Inside Server's Comm Thread 2 ");
// EXCEPTION OCCURS IN THE LINE BELOW.
mInput = new ObjectInputStream(new BufferedInputStream(this.clientSocket.getInputStream()));
}
You can't mix streams and readers/writers on the same socket if any of them is buffered. In this situation I would use the object stream for everything.

IO and EOF Exception on sending and receiving byte to and from server

I am trying to create a server and client application on two android Phone(Nexus 4).One Phone as client and other as server. But at the server side I am getting an error of EOF exception while reading the incoming data and at the client side I am getting IO exception while writing some byte to Socket outputStream. Can someone enlighten me what I am doing wrong?
Client side Code
// Send only one byte to server
while (!Thread.currentThread().isInterrupted()) {
try {
Log.d(TAG,"Entering into the IO exception block");
byte[] image_data = new byte[3];
String send_string = new String(image_data);
// Create a Output Stream to send the bytes back to server
OutputStream out;
out = s.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
Log.d(TAG,"Created data output Stream");
dos.writeUTF(send_string);
/*
dos.writeInt(image_data.length);
dos.write(image_data, 0, image_data.length);
Log.d(TAG,"Writing the ByteArray into Socket ");
*/
out.close();
dos.flush();
dos.close();
s.close();
} catch (IOException e1) {
Log.d(TAG,"Exception while writing to Socket");
e1.printStackTrace();
}
}
Server side Code : Exception while dis.readFully(ClientByteArray)
if (s == null)
s = ss.accept();
Log.d(TAG,"Socket server is closed " + ss.isClosed() +", Recieved Buffer Size = " + ss.getReceiveBufferSize());
Log.d(TAG,"Accepted Client socket at server");
byte[] ClientByteArray = new byte[ss.getReceiveBufferSize()];
InputStream in;
in = s.getInputStream();
DataInputStream dis = new DataInputStream(in);
dis.readFully(ClientByteArray);
Log.d(TAG,"Data recieved from Client, Bytes = " + ClientByteArray.length);
You are writing with writeUTF(), so you should be reading with readUTF().

Unable to receive UDP Packets from a specific IP

I am trying to connect to a datalink that sends UDP packet. These packets are not 'broadcasted.' (I understand that there is two ways to send a UDP backet, to broadcast such that any machine can receive on the network, or to send to a specific IP...my understanding is limited to this, but I know that they are sent to a specific IP).
I am unable to receive the packets on my Android app I am testing with (Galaxy S3...internet permission has been enabled in the Manifest). I am binding to the host machine (IP) and its associated port. The packet traffic is seen in WireShark.
Here is my code. Anything glaring I am omitting?
try {
Log.d("UDP", "1");
DatagramSocket serverSocket = new DatagramSocket();
Log.d("UDP", "2");
InetAddress address = InetAddress.getByName(UDP_IP);
Log.d("UDP", "2a");
serverSocket.connect(address, UDP_SERVER_PORT);
Log.d("UDP", "2b");
serverSocket.setSoTimeout(5000); //5 sec wait for the client to connect
Log.d("UDP", "3");
byte[] data = new byte[1024];
Log.d("UDP", "4");
DatagramPacket packet = new DatagramPacket(data, data.length);
Log.d("UDP", "5");
Log.d("UDP", "S: Receiving...");
serverSocket.receive(packet);
//lock.release();
retVar = 1;
Log.d(" Received Packet", "Good");
}
catch (Exception e) {
Log.e("UDP", "S: Error", e);
}

Receive UDP packets on Android

I try to send and receive UDP packets continuously between an Android app and a server.
Is there any way to make that happen ?
My current networking code (running in a Thread) is shown bellow. The client is connected through 3G. The port configured client side is 1088.
The server just echo the packet to the client when received.
The server receive the packet correctly from the client but the client doesn't receive anything back.
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
Log.d(TAG, "S: Connecting...");
DatagramSocket socket = new DatagramSocket();
DatagramSocket receive_socket = new DatagramSocket(SERVERPORT, InetAddress.getByName("0.0.0.0"));
while(running) {
DatagramPacket packet_send = new DatagramPacket(msg, msg.length, serverAddr, SERVERPORT);
Log.d(TAG, "C: Sending: '" + new String(msg) + "'");
socket.send(packet_send);
// Prepare a UDP-Packet that can contain the data we want to receive
DatagramPacket packet = new DatagramPacket(buf, buf.length);
Log.d(TAG, "S: Receiving...");
// Receive the UDP-Packet
receive_socket.receive(packet);
Log.d(TAG, "S: Received: '" + new String(packet.getData()) + "'");
synchronized (this) {
wait(500);
}
}
I suspect the 3G connection is NATed (the server reports a port different from 1088).
If so, is there anything I can do to overcome that ?
Or is there anything wrong I do in my code ?
Turned out the code was working fine, the 3G service provider was blocking some UDP packets.

android UDP connection, not receiving any data

Im a newbie in this so please escuse me if i ask dumb questions.
Im trying to make a UDP connection between Eclipse's PC Emulator & a android phone
(or between two android phone devices).
I have a router and the phone connects to the internet thru router's wifi network. The PC is on same network also (direct cable router-PC connection). Im trying to send some text data from Server thread to Client thread but nothing is received/sent. :(
The Server java class (RE-EDITED, Server receives msg. from Client):
public class server implements Runnable
{
// the Server's Port
public static final int SERVERPORT = 6000;
// running Server thread.
public void run()
{
Log.d("redwing","server thread started.");
DatagramSocket serverSocket = null;
try
{
// Open Server Port
serverSocket = new DatagramSocket(server.SERVERPORT);
byte[] receiveData = new byte[32];
byte[] sendData = new byte[32];
// loop until "server_finished" becomes False.
while(createserver.server_finished)
{
if(renderer.gGL!=null) // ignore me, just a null pointer checker
{
// waiting for the incoming client's message packet
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
renderer.recv = new String(receivePacket.getData());
Log.d("server","packet received from client, ETA " + timing.getNow() + " " + renderer.recv); // timing getNow - just returns current system minute & second.
// server is replying to the client back with a message.
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
sendData = new String("server msg").getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
renderer.sent = new String(sendData, 0, sendData.length);
Log.d("server","packet sent to client, ETA " + timing.getNow() + " " + renderer.sent); // timing getNow - just returns current system minute & second.
}
}
// close the socket
if(serverSocket!=null) serverSocket.close();
serverSocket = null;
}
catch (Exception e)
{
Log.e("server", "Error", e);
if(serverSocket!=null) serverSocket.close();
serverSocket = null;
}
finally
{
if(serverSocket!=null) serverSocket.close();
serverSocket = null;
}
Log.d("redwing","server thread terminated.");
}
}
and the Client java class (RE-EDITED, Client does not receive msg from Server) :
public class client implements Runnable
{
public static final int CLIENTPORT = 5000;
// running Client thread.
public void run()
{
Log.d("redwing","client thread started.");
DatagramSocket clientSocket = null;
try
{
// getting local address
clientSocket = new DatagramSocket(server.SERVERPORT);
InetAddress IPAddress = InetAddress.getByName("192.168.0.100");
// displaying IP & hostname.
Log.d("client", "IP: " + IPAddress.getHostAddress() + " Name: " + IPAddress.getHostName());
byte[] sendData = new byte[32];
byte[] receiveData = new byte[32];
// Loop until client_finished becomes False.
while(createclient.client_finished)
{
if(renderer.gGL!=null) // ignore me, just a null pointer checker
{
// sending a message to the server
sendData = timing.getNow().getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, client.CLIENTPORT);
clientSocket.send(sendPacket);
renderer.sent = new String(sendData,0,sendData.length);;
Log.d("client","packet sent to server, ETA " + timing.getNow());
// waiting for the server packet message.
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
renderer.recv = new String(receivePacket.getData());
Log.d("client","packet received from server, ETA " + timing.getNow());
}
}
// close the socket
if(clientSocket!=null) clientSocket.close();
clientSocket = null;
}
catch (Exception e)
{
Log.e("client", "Error", e);
if(clientSocket!=null) clientSocket.close();
clientSocket = null;
}
finally
{
if(clientSocket!=null) clientSocket.close();
clientSocket = null;
}
Log.d("redwing","client thread terminated.");
}
}
the Permisions are enabled in the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<user-permission android:name="android.permission.NETWORK" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
I'm running the Server on the android PC Emulator, and the Client on my android Phone.
Both Client & Server threads run just fine but ... the problem is that i dont get any data exchanged between them. The client doesn't receive anyting and the server doesnt receive anything. The packets are sent but nothing received .
What im doing wrong ?
Please help me.
Thank you in advance.
After running your emulator, type it in command prompt - "telnet localhost ", then type "redir add udp:5000:6000". Connect client with port number 5000 and open udp server with port number 6000. Then you can receive client message from udp server.
Take a look for details
clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("<pc ip>"); // instead of "localhost"
public static final String SERVERIP = "127.0.0.1"; // 'Within' the emulator!
public static final int SERVERPORT = 6000;
/* Retrieve the ServerName */
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
DatagramSocket socket = new DatagramSocket(SERVERPORT, serverAddr);

Categories

Resources