简体   繁体   中英

Multicast packet not received by MulticastSocket on any localhost client

Intro

There are a number of tutorials on creating a multicast publisher and receiver.

I used the one found here with a few modifications.

A few others:

note that these tutorials are all quite similar.

Details:

The server runs on port 7777 and sends datagrams to 224.0.0.0 (I tested a couple of other ip's in the multicast range: 224.0.0.0 to 239.255.255.255 , but these didn't work)

Client then joins the multicast group 224.0.0.0 and waits for a packet response (run as a thread)

extra: I send a message like: 123.23.13.12[host-name]:1234 as the datagram data.

Problem:

Multicast packets from server (on localhost) not reaching client (on localhost).

Clients include a java console application (code found below) and Android application on Android Emulator. Both clients do not receive multicast packets.

I know that the multicast packets are being sent as this is shown in Wireshark

Below you will find a basic example of that which I have.

TL;DR : Server sends multicast packets (confirmed via Wireshark) but client doesn't receive them.

Suggestions are very welcome!

UPDATE

Based on Just another Java programmer 's comment, I check my firewall. Lo and behold, my firewall was dropping on the input and forward chains. I set this to accept all incoming (temporarily)

Based on Ron Maupin 's comments.

  • I have changed the message sent to exclude the hostname, thus the message sent is 123.12.13.23:1234
  • I have changed the multicast send address to 239.254.0.0 which is within the specified range (see Ron's comment)
  • the multicast port is set to 7777
  • the outgoing interface is set with s.setInterface(InetAddress.getLocalHost()) in the broadcastServer() try catch block

With these changes applied, the client(s) still do not receive any packets.

Code:

Server Side (Console App):

String multicastAddress = "239.254.0.0", multicastPort = 7777;

private void broadcastServer() {
    String message = null;
    MulticastSocket s = null;
    InetAddress local = null, group = null;
    InetAddress[] allByName;
    try {
        local = InetAddress.getLocalHost();
        s = new MulticastSocket(multicastPort);
        s.setReuseAddress(true);
        s.setInterface(local)
        s.joinGroup(InetAddress.getByName(multicastAddress));
        group = InetAddress.getByName(multicastAddress);
    } catch (SocketException e) {
        e.printStackTrace();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    MulticastSocket socket = s;

    // getNetworkIP() gets lan network ip
    // serverport = 1025
    message = local.getHostAddress() + ":" + String.valueOf(serverPort);
    byte[] buf = message.getBytes();
    DatagramPacket packet = new DatagramPacket(buf, buf.length, group, multicastPort);

    thdBroadcaster = new Thread(() -> {
        while (bRunServer) {
            try {
                Thread.sleep(1000);
                printf("[Broadcast] Broadcasting...");
                socket.send(packet);
                printf("OK\n");
                printf("");
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        socket.close();
    });
    thdBroadcaster.start();
}

Client Side (Console app):

String multicastAddress = "239.254.0.0", multicastPort = 7777;

private void startServerListenerThread() {
    Thread thdServerListener = new Thread(new Runnable() {
        @Override
        public void run() {
            MulticastSocket socket = null;
            InetAddress group = null;
            try {
                socket = new MulticastSocket(multicastPort);
                socket.setReuseAddress(true);
                group = InetAddress.getByName(multicastAddress);
                socket.joinGroup(group);

                handleServerBroadcasts(socket);
                socket.leaveGroup(group);
                socket.close();

            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        private void handleServerBroadcasts(final MulticastSocket socket) {
            while (true){
                try {
                    byte[] buf = new byte[256];
                    DatagramPacket packet = new DatagramPacket(buf, buf.length);
                    socket.receive(packet);
                    String received = new String(packet.getData());

                    String address = received.substring(0, received.indexOf(":"));
                    String port = received.substring(received.indexOf(":") + 1);

                    System.out.println();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (Exception x){
                    x.printStackTrace();
                }
            }
        }
    });
    thdServerListener.start();
}

The solution ended up being a trivial change.

Resolving the issue was as simple as changing:

s = new MulticastSocket(multicastPort);

to

s = new MulticastSocket();

on the server side ONLY

Note: The firewall is a requirement, check if multicast packets are allowed through. The interface I used is localhost, not a requirement though. However this can be set by getting the specified interface you need.

UPDATE

EJP's comment:

I changed the port used to 8888 . This port was used to send server datagrams and for the client to connect on with their MulticastSocket

You are calling setReuseAddress() after binding the socket. It has no effect. You need to create an unbound MulticastSocket , call setReuseAddress() , and then bind it.

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