简体   繁体   中英

UDP Broadcast in Java

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;

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, eg 192.168.1.255.

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

如果要接收数据报,则需要将(bind)()绑定到本地端点(地址+端口)。

You are sending and receiving the packet on same device. You could separate send and receive ports (eg 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM