UDP Broadcast in Java
Asked Answered
L

4

6

Morning.

I'm pretty new in Java and socket connections but I'm trying to send out a UDP packet/broadcast on 255.255.255.255 on port 8001 to a device. I can get the data to send just fine, however when it comes time to receive the data the connection times out. I have a packet sniffer and I can see the packet send and then the device respond.

I'm pretty sure it is a rookie mistake that I'm missing in my code but I've been stuck on it for awhile and any help would be appreciated.

 m_Socket = new DatagramSocket(m_SERVERPORT);
 InetAddress address = InetAddress.getByName(m_SERVERIP);


 m_DataPack = new DatagramPacket(m_SERVERCMD.getBytes(), m_SERVERCMD.getBytes().length,
 address, m_SERVERPORT);
 m_Socket.setBroadcast(true);
 m_Socket.connect(address, m_SERVERPORT);

 m_Socket.send(m_DataPack);
 m_DataPack = new DatagramPacket(data, data.length,
 address, m_SERVERPORT);


 m_Socket.receive(m_DataPack); // This is where it times out


 data = m_DataPack.getData();
 String received = data.toString();
 System.out.println("Received: " + received);
 m_Socket.close();

Thanks and Gig'Em.

EDIT:

I'm not sure if this helps but when I watch the m_Socket object I can see the following right before it sends:

bound = true;
close = false;
connectedAddress = Inet4Address (id = 32) (-1,-1,-1,-1);
connectedPort = 8001;
connectState = 1;
created = true;
impl = PlainDatagramSocketImpl;
oldImpl = false;

and the m_DataPack object is the following:

address = Inet4Address (id = 32) (-1,-1,-1,-1);
bufLength = 6 (size of packet I'm sending is 6 char long);
offset = 0;
port = 8001;
Lonne answered 1/6, 2010 at 14:43 Comment(2)
You do realize that your Gig'Em alienates some graduates of one of the larger CS programs in America, right?Nesselrode
@Nesselrode for those non-Texan who are wondering what it means: en.wikipedia.org/wiki/… (yes, I had to look it up ;))Stag
A
12

This doesn't make sense. You are broadcasting, which is 1-to-many, and you are also connecting, which is 1-to-1. Which is it?

Lose the connect. And lose the 255.255.255.255. This has been heavily deprecated for about 20 years. Use a subnet-local broadcast address, e.g. 192.168.1.255.

Abeyta answered 2/6, 2010 at 3:53 Comment(0)
C
3

You can also take a look at MulticastSocket described at Broadcasting to Multiple Recipients. Hope this helps.

Chloe answered 16/2, 2012 at 8:6 Comment(0)
F
1

If you want to receive a datagram you need to bind() to the local endpoint (address + port).

Figurative answered 1/6, 2010 at 14:56 Comment(3)
In the bind function I need to set the local endpoint to an address and port through a SocketAddress. What is the best way to do this? I know in the DatagramPacket Class there is a getSocketAddress(); function so that doesn't help me.Lonne
I did try m_DataPack = new DatagramPacket(data, data.length, InetAddress.getLocalHost(), m_SERVERPORT); and then the m_Socket.bind(m_DataPack.getSocketAddress()); but it throws an exception saying the socket has already been bound.Lonne
He is binding, that's what new DatagramSocket(int port) does.Abeyta
Z
0

You are sending and receiving the packet on same device. You could separate send and receive ports (e.g send on 8001, receive on 8002). And run send and receive codes as separate threads. If both device must find each other (or one device find itself).

import java.io.IOException;
import java.net.*;

Receiving:

private DatagramSocket getReceiveSocket() throws UnknownHostException, SocketException {
    if (receiveSocket == null) {
        receiveSocket = new DatagramSocket(8002, InetAddress.getByName("0.0.0.0")); // 0.0.0.0 for listen to all ips
        receiveSocket.setBroadcast(true);
    }
    return receiveSocket;
}

public void receive() throws IOException {
    // Discovery request command
    byte[] buffer = "__DISCOVERY_REQUEST__".getBytes();
    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
    getReceiveSocket().receive(packet);
    System.out.println("Discovery package received! -> " + packet.getAddress() + ":" + packet.getPort());
    // Get received data
    String data = new String(packet.getData()).trim();
    if (data.equals("__DISCOVERY_REQUEST__")) { // validate command
        // Send response
        byte[] response = new byte["__DISCOVERY_RESPONSE".length()];
        DatagramPacket responsePacket = new DatagramPacket(response, response.length, packet.getAddress(), packet.getPort());
        getReceiveSocket().send(responsePacket);
        System.out.println("Response sent to: " + packet.getAddress() + ":" + packet.getPort());
    } else {
        System.err.println("Error, not valid package!" + packet.getAddress() + ":" + packet.getPort());
    }
}

Sending:

private DatagramSocket getSendSocket() throws UnknownHostException, SocketException {
    if (sendSocket == null) {
        sendSocket = new DatagramSocket(8001, InetAddress.getLocalHost());
        sendSocket.setBroadcast(true);
    }
    return sendSocket;
}

public void send() throws IOException {
    // Discovery request command
    byte[] data = "__DISCOVERY_REQUEST__".getBytes();
    DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("255.255.255.255"), 8002);
    getSendSocket().send(packet);
    System.out.println("Discovery package sent!" + packet.getAddress() + ":" + packet.getPort());

    // Discovery response command
    byte[] response = new byte["__DISCOVERY_RESPONSE__".length()];
    DatagramPacket responsePacket = new DatagramPacket(response, response.length);
    getSendSocket().receive(responsePacket);
    System.out.println("Discovery response received!" + responsePacket.getAddress() + ":" + responsePacket.getPort());
    String responseData = new String(responsePacket.getData()).trim();
    if (responseData.equals("__DISCOVERY_RESPONSE__")) { // Check valid command
        System.out.println("Found buddy!" + responsePacket.getAddress() + ":" + responsePacket.getPort());
    }
}

Of course should put this code in a loop in a thread. Based on this example: https://demey.io/network-discovery-using-udp-broadcast/

UPDATE

The link above is dead. But same method described here also: https://www.baeldung.com/java-broadcast-multicast

Zach answered 24/7, 2018 at 7:50 Comment(2)
The link that you provided at the end of your answer is dead, please insert a new link or provide an example from a site and put it in your answer.Ideational
@Alex thanks for warning. Added a new link includes similar codeZach

© 2022 - 2024 — McMap. All rights reserved.