UDP Sending and Receiving - java

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!

Related

Java multiple UDP clients listening same port

Say I start a simple UDP server: nc -u localhost 10000
And a simple UDP client: nc -ul 10000
Then is it possible, in Java, to receive the messages sent by the server without getting an "Address already in use" exception because there's already a client?
EDIT: here's the code I'm using:
DatagramSocket socket = new DatagramSocket(port);
new Thread(() -> {
try {
while(true) {
byte[] receiveData = new byte[256];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
socket.receive(receivePacket);
String message = new String( receivePacket.getData(), 0, receivePacket.getLength()).trim();
}
}
catch (SocketException ignore) {}
catch (IOException e) { e.printStackTrace(); }
}).start();
This leads to a java.net.BindException: Address already in use (bind failed).
Using this:
DatagramSocket socket = new DatagramSocket(null);
socket.setOption(SO_REUSEPORT, true);
socket.setOption(SO_REUSEADDR, true);
new Thread(() -> {
try {
while(true) {
byte[] receiveData = new byte[256];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
socket.receive(receivePacket);
String message = new String( receivePacket.getData(), 0, receivePacket.getLength()).trim();
}
}
catch (SocketException ignore) {}
catch (IOException e) { e.printStackTrace(); }
}).start();
Produces no exception but I won't receive the messages sent by the server.
EDIT 2: in the real situation, the server is broadcasting messages.
This should be possible by utilizing StandardSocketOptions.SO_REUSEPORT:
For datagram-oriented sockets the socket option usually allows multiple UDP sockets to be bound to the same address and port.
The Linux Kernel supports this since 3.9.
On Windows, you might need to utilize SO_REUSEADDR, but I'm not exactly sure.
Using SO_REUSEADDR
The SO_REUSEADDR socket option allows a socket to forcibly bind to a port in use by another socket.

Cannot bind Address already in use

This is my udp_broadcast server code where iam listening on 0.0.0.0
try{
socket = new DatagramSocket (7777,InetAddress.getByName("0.0.0.0"));
socket.setBroadcast(true);
while(true)
{
System.out.println(getClass().getName()+"ready recieve broadcast packets!");
//recieve a packet
byte[] recvBuf = new byte[15000];
DatagramPacket packet = new DatagramPacket(recvBuf,recvBuf.length);
socket.receive(packet);
System.out.println(getClass().getName() +"packet recieved from :" +packet.getAddress().getHostAddress());
System.out.println("data is "+new String(packet.getData()));
String message = new String(packet.getData()).trim();
if(message.equals("p2p_project_node"))
{
byte [] senddata = "I_found_you_did_YOU".getBytes();
DatagramPacket sendpacket= new DatagramPacket(senddata,senddata.length,packet.getAddress(),packet.getPort());
socket.send(sendpacket);
System.out.println("packet sent to "+sendpacket.getAddress().getHostAddress());
}
}
}
on client side iam broadcasting packet 255.255.255.255 so that i get a reply from server
eventually and i endup in getting server ip address
udp_client_side code
try {
c = new DatagramSocket();
c.setBroadcast(true);
byte [] sendData = "p2p_project_node".getBytes();
//this is broadcasting to 255.255.255.255a
try{
DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length,InetAddress.getByName("255.255.255.255"),7777);
c.send(sendPacket);
System.out.println("rewuest sent to 255.255.255.255");
}
catch(Exception e) {
System.out.println("exception 255.255" +e);
}
on the server side iam getting error saying that
Exception java.net.BindException "Address already in use :cannot bind"
where am i going wrong if someone could help me it would be great Thanks in advance
The address is already in use. You cannot bind your socket to that address. Some other process already has a UDP socket bound to that poet. Possibly a previous instance of your own program.
Don't broadcast to 255.255.255.255. It was deprecated twenty years ago. Use the subnet broadcast address, or better still use multicast.
You can bind your socket to that port, if this port is occupied by a previous instance of your own program. You need to use "reuse" parameter in all instances of your program. Call .setReuseAddress(true); before binding.

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

Server client simple program

So I try to create a simple server client application.
I have the server, which multicast messages to the subscribed clients.
The clients can obviously subscribe or unsubscribe.
Here is the server side code for the socket
try // create DatagramSocket for sending and receiving packets
{
socket = new DatagramSocket( 6666 );
} // end try
catch ( SocketException socketException )
{
System.exit( 1 );
} // end catch
I have also created a thread which waits for incoming pockets
while(true)
{
try // receive packet, display contents, return copy to client
{
byte[] data = new byte[ 100 ]; // set up packet
DatagramPacket receivePacket =
new DatagramPacket( data, data.length );
socket.receive( receivePacket ); // wait to receive packet
String Message = receivePacket.getData().toString();
.........
Here is the client side
try {
socket = new DatagramSocket();
} catch (SocketException ex) {
displayArea.append( ex + "\n" );
}
Here I try to send the packet
byte[] data = message.getBytes(); // convert to bytes
try {
// create sendPacket
DatagramPacket sendPacket = new DatagramPacket( data,
data.length, InetAddress.getLocalHost(), 6666 );
} catch (UnknownHostException ex) {
displayArea.append( ex + "\n" );
}
Well, the problem is that I don't think the packet reaches the server, I know the thread is waiting for the packet, I can see in debug that it does reaches the socket.receive part, however, nothing happens.
I'm using the client and server on the same computer.
Any idea what am I doing wrong?
Thanks.
byte[] data = message.getBytes(); // convert to bytes
try {
DatagramPacket sendPacket =
new DatagramPacket( data, data.length, InetAddress.getLocalHost(), 6666 );
socket.send( sendPacket ); //<<<<<<<<<<<<<<<<<<< REQUIRED
}
catch( UnknownHostException ex ) {
displayArea.append( ex + "\n" );
}

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