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;
user355528
  • 61
  • 1
  • 1
  • 3
  • You do realize that your Gig'Em alienates some graduates of one of the larger CS programs in America, right? – jasonmp85 Jun 02 '10 at 04:29
  • 1
    @jasonmp85 for those non-Texan who are wondering what it means: https://en.wikipedia.org/wiki/Traditions_of_Texas_A%26M_University#Gig_.27em (yes, I had to look it up ;)) – Matthieu Oct 03 '17 at 13:34

4 Answers4

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.

user207421
  • 305,947
  • 44
  • 307
  • 483
3

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

Zorayr
  • 23,770
  • 8
  • 136
  • 129
1

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

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • 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. – user355528 Jun 01 '10 at 15:05
  • 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. – user355528 Jun 01 '10 at 15:06
  • 1
    He is binding, that's what new DatagramSocket(int port) does. – user207421 Jun 02 '10 at 03:54
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

user12043
  • 396
  • 1
  • 3
  • 12