UDP client sending data to server, but not receiving response - java

I am creating a simple Android app which can communicate with my PC. On my computer I have a very simple UDP server in Java.
public void run(){
try{
DatagramSocket serverSocket = new DatagramSocket(port);
byte[] receiveData = new byte[8];
byte[] sendData = new byte[8];
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData());
System.out.println("RECEIVED: " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
String sendString = "polo";
sendData = sendString.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}catch (Exception e){
}
}
and I have another simple piece of code inside my android app which sends a UDP packet to the server and awaits the response.
public void checkServerOnline(View v) {
try {
int port = 46001;
DatagramSocket clientSocket = new DatagramSocket();
clientSocket.setSoTimeout(1800);
InetAddress IPAddress = InetAddress.getByName(host);
byte[] sendData = new byte[8];
byte[] receiveData = new byte[8];
String sentence = "marco";
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
clientSocket.close();
} catch (Exception e) {
}
The problem I am having is that my Client is timing out waiting for a response. The server is definitely receiving the string "marco" and is presumably sending the response "polo", but the client is not receiving it. I've tried removing the timeout on the client, but it just freezes up until I force close the application.
Can anyone see an error in my code? I can't understand why it won't work. I've managed to successfully setup a TCP Server and client with the same setup, but cannot seem to do UDP.

The server is sending to the wrong port. It should send to the port in the received datagram, not its own port. It is simplest to reuse the request datagram and just change the data to the response data: the return address is already there.

Related

JAVA UDP Server Can't receive Packet

I have a sample code as below and the socket is bound to IP 10.10.88.11 and port 9876. I tested with the 2 conditions with wireshark as below. Both PCs are in the same subnet.
Send UDP packet from the same pc (10.10.88.11) - UDP Server able to receive
Send UDP packet from another pc ( 10.10.88.10) - UDP Server unable to receive but Wireshark (at 10.10.88.11) able to capture the packets
I have searched the internet but can't find a solution for this. Is there anything i did wrong in creating the InetScoketAddress?
import java.io.*;
import java.net.*;
public class UDPServer {
public static void main(String args[]) throws Exception {
InetSocketAddress address = new InetSocketAddress("10.10.88.11", 9876);
DatagramSocket serverSocket = new DatagramSocket(address);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
System.out.println("Waiting to receive");
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData());
System.out.println("RECEIVED: " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
String capitalizedSentence = sentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}
}
I believe Wireshark is able to grab packets before they are evaluated by the firewall, meaning that you will detect them but they will never reach the java app. Did you try deactivating your firewall ?

How can I create a simple UDP client-server-communication in Java?

Where can I find details on UDP in Java and how is a basic UDP communcation established?
This page provides detailed information on how to create a UPD server and client.
In essence, you create a server like this:
// Setup the socket
DatagramSocket socket = new DatagramSocket(12345);
// Receive a packet
byte[] buffer = new byte[512];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
// Do something with the data in the buffer
// and if necessary receive more packets
// Close the socket
socket.close();
On the client side, you can then send a packet like this:
// Create a socket
DatagramSocket socket = new DatagramSocket();
// Create a buffer and fill it with your data
byte[] buffer = new byte[512];
...
// Send the packet
InetAddress address = InetAddress.getByName("127.0.0.1");
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, 12345);
socket.send(packet);
// Close the socket
socket.close();

Java: UDP behind NAT

i have made a video conferencing application in java. It is based on UDP as it should be. It works well on LAN. Now I am switching it to WAN. After a lot of reading about problems in UDP transmission behind NAT (as there will be users behind different routers). I tried to implement hole punching as read. But its not working. I am using a client-server-client architecture. More precisely, every client sends its images(or frames) to server, which then forwards them to other clients. For this i am using the client's IP and port assigned to them by the router. The server then sends the packets to clients. But the packets are still blocked by the router. Can anyone tell me what should be a reliable solution to this? Or there is any library to achieve hole punching efficiently?
==================================================================================
client code:
//some code
final Socket client = new Socket(IPaddr, port); // tcp connection
...
// code for some gui components...
...
String message2="video";
clientSocketReceiver = new DatagramSocket();
String ip = "x.x.x.x";
InetAddress IPAddress = InetAddress.getByName(ip);
ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
baos1.write(message2.getBytes());
baos1.write('\n');
baos1.flush();
byte[] message2InByte = baos1.toByteArray();
baos1.close();
clientSocketReceiver.send(new DatagramPacket(message2InByte, message2InByte.length, IPAddress, 8876));
...
//some code....
...
//thread for receiving images..
while (true) {
byte[] receiveData = new byte[50000];
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
clientSocketReceiver.receive(receivePacket);
InputStream in = new ByteArrayInputStream(receivePacket.getData());
buffImage = ImageIO.read(in);
...
//code for displaying images on GUI
...
}
//==========================================================================
=========================================================================== =
server code:
//code for storing client's ip and port. runs only when a new client is accepted by tcp socket....
serverSocket=new DatagramSocket(8876); //declared at starting of code
while (checked==false ) {
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
serverSocket.receive(receivePacket);
String data = new String(receivePacket.getData());
data = data.trim();
if (data.equals("video")) {
vx.add(receivePacket.getAddress().getHostAddress()); // storing ip
String tmp = "" + receivePacket.getPort();
vv.add(tmp); //storing port. vv and vx r vectors
checked=true;
}
}
======================================
//thread for receiving/sending images from/to clients
DatagramSocket serverSocket2 = new DatagramSocket(9876);
byte[] receiveData = new byte[50000];
while (true) {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket2.receive(receivePacket);
InputStream in = new ByteArrayInputStream(receivePacket.getData());
bImage = ImageIO.read(in);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bImaget, "jpg", baos);
baos.flush();
byte[] imageInByte = baos.toByteArray();
baos.close();
for (int i = 0; i < vx.size() && i < vv.size(); i++) {
serverSocket2.send(new DatagramPacket(imageInByte, imageInByte.length, InetAddress.getByName(vx.elementAt(i).toString()), Integer.parseInt(vv.elementAt(i).toString())));
}
}
=============================================

DatagramSocket fails on Android with 'Try Again'

I am trying to send DatagramPackets (UDP) in my Android application:
//create a byte to receive data
mClientSocket = new DatagramSocket();
byte[] receiveData = new byte[MAX_RECEIVE_DATA_SIZE_BYTES];
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
// Set a receive timeout
mClientSocket.setSoTimeout(timeout);
// receive the packet
mClientSocket.receive(receivePacket);
return new String(receivePacket.getData(), 0,
receivePacket.getLength());
I get the following error:
Try again
Am I missing something here?
Well to send the UDP you'd need something similar to:
Server:
String messageStr="Hello Android!";
int server_port = 12345;
DatagramSocket s = new DatagramSocket ();
InetAddress local = InetAddress .getByName("192.168.1.102");
int msg_length=messageStr.length();
byte[] message = messageStr.getBytes();
DatagramPacket p = new DatagramPacket (message, msg_length,local,server_port);
s.send(p);
Client:
String text;
int server_port = 12345;
byte[] message = new byte[1500];
DatagramPacket p = new DatagramPacket (message, message.length);
DatagramSocket s = new DatagramSocket (server_port);
s.receive(p);
text = new String (message, 0, p.getLength());
Log.d("Udp tutorial","message:" + text);
s.close();
References:
Simple UDP communication example

Stop and wait UDP server

I am trying to program a Java stop-and-wait UDP server and I have gotten this far with the server but I am not sure where to go next. I want the client to send a message to the server, set a timeout, wait for a response, if it doesn't get one, then resend the packet, if it does then increment the sequence no. until it get to ten and keep send and receiving messages with the server.
I have gotten this far, how do I fix this ? :
import java.io.*;
import java.net.*;
public class Client {
public static void main(String args[]) throws Exception {
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
InetAddress IPAddress = null;
try {
IPAddress = InetAddress.getByName("localhost");
} catch (UnknownHostException exception) {
System.err.println(exception);
}
//Create a datagram socket object
DatagramSocket clientSocket = new DatagramSocket();
while(true) {
String sequenceNo = "0";
sendData = sequenceNo.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 6789);
clientSocket.send(sendPacket);
clientSocket.setSoTimeout(1);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
if(clientSocket.receive(receivePacket)==null)
{
clientSocet.send(sendPacket);
}else { //message sent and acknowledgement received
sequenceNo++; //increment sequence no.
//Create a new datagram packet to get the response
String modifiedSentence = sequenceNo;
//Print the data on the screen
System.out.println("From : " + modifiedSentence);
//Close the socket
if(sequenceNo >= 10 ) {
clientSocket.close();
}
}}}}
The first problem I can see (apart from the mistyped variable names which will stop your code compiling) is your socket timeout: if the socket timeout expires, the receive function will throw a SocketTimeoutException which your code does not handle. receive does not return a value, so the result can't be compared with null. Instead, you need to do something like this:
try {
clientSocket.receive(receivePacket);
sequenceNo++;
... // rest of the success path
} catch (SocketTimeoutException ex) {
clientSocket.send(sendPacket);
}

Categories