Stop and wait UDP server - java

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);
}

Related

UDP Sending and Receiving

I've looking into multiple ways to do this and nothing has helped/worked new to Java UDP packets.
My code for Android is started via a service and it runs on a new thread.
Code for waiting:
try {
int port = 58452;
// Create a socket to listen on the port.
DatagramSocket dsocket = new DatagramSocket(port);
// Create a buffer to read datagrams into. If a
// packet is larger than this buffer, the
// excess will simply be discarded!
byte[] buffer = new byte[2048];
// Create a packet to receive data into the buffer
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// Now loop forever, waiting to receive packets and printing them.
while (true) {
// Wait to receive a datagram
dsocket.receive(packet);
// Convert the contents to a string, and display them
String msg = new String(buffer, 0, packet.getLength());
System.out.println(packet.getAddress().getHostName() + ": "
+ msg);
// Reset the length of the packet before reusing it.
packet.setLength(buffer.length);
}
} catch (Exception e) {
System.err.println(e);
}
Code for sending:
try {
String host = "MY PHONES IP";
int port = 58452; //Random Port
byte[] message = "LAWL,LAWL,LAWL".getBytes();
// Get the internet address of the specified host
InetAddress address = InetAddress.getByName(host);
// Initialize a datagram packet with data and address
DatagramPacket packet = new DatagramPacket(message, message.length,
address, port);
// Create a datagram socket, send the packet through it, close it.
DatagramSocket dsocket = new DatagramSocket();
dsocket.send(packet);
dsocket.close();
System.out.println("Sent");
} catch (Exception e) {
System.err.println(e);
}
}
It sends fine but won't receive on Android. Please help!
Also my Logcat output: http://pastebin.com/Rfw5mSKV
Thanks
-Fusion
http://systembash.com/content/a-simple-java-udp-server-and-udp-client/
I used that to and it works! Thanks to /u/TarkLark or Reddit!

Can not get UDP packets

I am trying to get UDP packets ,sent by device via WiFi, on my pc.
The device (kind of card) send every 2 seconds new packet.
The problem is that i do not get the packets on java client i have on my pc.
I see the packets on Wireshark.
Here is my UDP client (java):
public static void main(String args[]) {
try {
int port = 80;
// Create a socket to listen on the port.
DatagramSocket dsocket = new DatagramSocket(port);
dsocket.setSoTimeout(10000);
byte[] buffer = new byte[2048];
// Create a packet to receive data into the buffer
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// Now loop forever, waiting to receive packets and printing them.
while (true) {
// Wait to receive a datagram
try
{
dsocket.receive(packet);
}
catch (SocketTimeoutException e) {
continue;
}
// Convert the contents to a string, and display them
String msg = new String(buffer, 0, packet.getLength());
System.out.println(packet.getAddress().getHostName() + ": "+ msg);
// Reset the length of the packet before reusing it.
packet.setLength(buffer.length);
}
} catch (Exception e) {
System.err.println(e);
}
}

Java why isn't the socket listening on the local port I specified in the constructor / bound to?

I'm having a weird problem, let's consider the following code :
import java.net.*;
import java.util.Enumeration;
public class Main{
public static void main(String args[]) throws Exception {
Inet4Address myIp = (Inet4Address)Inet4Address.getByName(Main.getLanIp());
InetSocketAddress myAddr = new InetSocketAddress(myIp, LocalportNumber);
if(myIp == null){
throw new Exception();
}
DatagramSocket socket = new DatagramSocket(myAddr);
socket.setReuseAddress(true);
InetAddress IPAddress = InetAddress.getByName("239.xxx.xxx.xxx");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
String sentence = "PAYLOAD";
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, distantPortNumber);
DatagramPacket receivePacket = new DatagramPacket(receiveData, 1024);
socket.send(sendPacket);
System.out.println("Packet sent");
socket.receive(receivePacket);
String modifiedSentence = new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
socket.close();
}
static public String getLanIp() throws SocketException{
InetAddress inet_addr = null;
NetworkInterface cur = null;
for (Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements();){
cur = interfaces.nextElement();
try {
if (cur.isLoopback())
{
continue;
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("interface " + cur.getName());
for (InterfaceAddress addr : cur.getInterfaceAddresses()){
inet_addr = addr.getAddress();
if ( !( inet_addr instanceof Inet4Address)){
continue;
}
System.out.println(" address: " + inet_addr.getHostAddress() + "/" + addr.getNetworkPrefixLength());
System.out.println(" broadcast address: " + addr.getBroadcast().getHostAddress());
}
}
return inet_addr.getHostAddress();
}
}
Execution trace :
"""
interface eth0
address: 192.168.0.20/24
broadcast address: 192.168.0.255
Packet sent
"""
When I run the preceding code, a packet is sent, the server answers but I still block on the receive method, I can see the incoming packet on wireshark reaching my computer. But when I try a : "netstat -npl", I see a java process listening on the port localPort. I tried a "nc -vvv -u 9393" from remote (lan) and then typed random sentences ... Nothing happened. I tried the same on local (with my external IP, with my loopback IP), same problem. Is there a list of known problems which could block the received udp packets between the kernel and the jvm ?
I found my problem : my iptable firewall ... I was blocking all the incoming traffic which was not an answer to my outgoing traffic. That's why I saw the traffic on wireshark but I didn't reached the java socket...
So the solution was to open my firewall -_-"

UDP client sending data to server, but not receiving response

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.

Java UDP message exchange works over localhost but not Internet?

Client A
import java.io.*;
import java.net.*;
import java.util.*;
public class ClientA
{
final private static int PORT = 5005; // arbitrarily assigned port to use
public static void main(String args[]) throws
IOException
{
DatagramSocket socket = new DatagramSocket(PORT); // create new connection on that port
while (true)
{
byte buffer[] = new byte[256]; // data buffer
DatagramPacket packet = new DatagramPacket(buffer, buffer.length); // new packet containing buffer
socket.receive(packet); // look for packet
String clientBMsg = new String(packet.getData()); // get data from received packet
InetAddress address = packet.getAddress(); // get address of received packet
System.out.println("ClientB at " + address + " says " + clientBMsg);
buffer = null;
String msgString = "I'm ClientA, vegetables are fun";
buffer = msgString.getBytes(); // put String in buffer
int port = packet.getPort(); // get port of received packet
packet = new DatagramPacket(buffer, buffer.length, address, port); // create new packet with this data
socket.send(packet); // send packet back containing new buffer!
System.out.println("Message Sent");
socket.close();
}
}
}
Client B
import java.io.*;
import java.net.*;
public class ClientB
{
final private static int PORT = 5005; // arbitrarily assigned port - same as server
public static void main(String args[]) throws
IOException {
// if (args.length == 0) { // requires host
// System.err.println
// ("Please specify host");
// System.exit(-1);
// }
// String host = args[0]; // user defined host
DatagramSocket socket = new DatagramSocket(); // open new socket
String host = "localhost";//"86.0.164.207";
byte message[] = new byte[256]; // empty message
String msgString = "Hello, I'm client B and I like trees";
message = msgString.getBytes(); // put String in buffer
InetAddress address = InetAddress.getByName(host); // determines address
System.out.println("Sending to: " + address); // tells user it's doing something
DatagramPacket packet = new DatagramPacket(message, message.length, address, PORT); // create packet to send
socket.send(packet); // send packet
System.out.println("Message Sent");
message = new byte[256];
packet = new DatagramPacket(message, message.length);
socket.receive(packet); // wait for response
String clientAreply = new String(packet.getData());
System.out.println("ClientA at " + host + " says " + clientAreply);
socket.close();
}
}
I don't understand why this works over localhost but when I put my IP address in, it just sends the message and nothing is received.
Can anyone point me in the right direction here?
Thank you!
You should use DatagramSocket's bind method to bind it to your internet interface, otherwise it only listens on 127.0.0.1 or localhost. Like this:
DatagramSocket socket = new DatagramSocket(null);
socket.bind(new InetSocketAddress(InetAddress.getByName("your.ip.add.ress"),5005);
In case you are behind your router then your should listen on the local IP address given to you by the router and use port forwarding to this address in your router settings.
I can suggest using Socket Test tool with TCP and UDP Sockets:
http://sockettest.sourceforge.net/
I used it to trouble shoot issues with a 2-way socket program. You can end-to-end test your link with two SocketTest programs and the compare results, etc. Very useful.

Categories