1

I'm trying to create a simple multicast communication between my PC (Ubuntu, client) and my phone (Android, server).

Unicast/TCP connections work without any problem, the defined port (37659) opens both on PC and phone. When trying to use a MulticastSocket, no ports get opened. nmap tells me the specified port (36963) is a TCP port and that it is closed. (While the receive-method is being executed).

Am I doing something wrong? Or is the firewall blocking the multicast sockets? (I've tried about 20 different ports and none worked..., currently using port 36963)

EDIT: Also with the firewall completely down, nmap tells me the port is closed...

The server's code (phone):

private void multicastLoop() {
        String res = Build.FINGERPRINT + "\n";
        final InetAddress group;
        final MulticastSocket socket;
        final DatagramPacket response;
        try {
            group = InetAddress.getByName("224.0.0.115");
            socket = new MulticastSocket(mport);
            socket.setLoopbackMode(true);
            socket.setSoTimeout(10000);
            socket.joinGroup(group);
            response = new DatagramPacket(res.getBytes(), res.length(), group, mport);
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }

        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                while(isRunning) {
                    try {
                        byte[] data = new byte[1024];
                        DatagramPacket dm = new DatagramPacket(data, data.length);
                        socket.receive(dm);
                        Log.d("udp", "received");
                        if (Arrays.equals(dm.getData(), "someone there".getBytes())) {
                            socket.send(response);
                        }
                    } catch (SocketTimeoutException e) {
                        continue;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                try {
                    socket.leaveGroup(group);
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        });
        t.start();
    }

The client's code (computer):

public String[] findServers() {
        String hello = "someone there";
        try {
            InetAddress group = InetAddress.getByName(mhost);
            MulticastSocket socket = new MulticastSocket(mport);
            socket.setLoopbackMode(true);
            socket.setSoTimeout(60000);
            socket.joinGroup(group);
            DatagramPacket p = new DatagramPacket(hello.getBytes(), hello.length(), group, mport);
            byte[] buffer = new byte[1024];
            socket.send(p);
            DatagramPacket r = new DatagramPacket(buffer, buffer.length);
            socket.receive(r);
            socket.leaveGroup(group);
            socket.close();
            String srinfo = "";
            byte[] data = r.getData();
            for (byte b: data)
                srinfo += (char) b;
            System.out.println("Server found at " + r.getAddress().getHostName() + ": " + srinfo);
        } catch (SocketTimeoutException e) {
            return new String[] {"timeout"};
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
s3lph
  • 4,575
  • 4
  • 21
  • 38
  • So the same code is running on android/the desktop? – turbo Jan 16 '14 at 21:16
  • Still waiting on clarification.. I have suggestions if this is android code, but it's not clear enough to me what exactly you are doing. – turbo Jan 17 '14 at 14:09
  • Sorry, was away the whole day... The code above runs on the phone. (phone=server). But the client (computer) doesn't work wither – s3lph Jan 17 '14 at 19:21
  • Your code does not run without modifications because you forget to provide some code (some one trying to replicate it will lose time). Also, be in mind that if you are sending thought a WiFi network packet losses are expected. – Diego C Nascimento Jan 21 '14 at 21:40
  • You are using the above code on both machines? If so, the timeout exception prevents the sending of the response packet, what I think is what you want. So you should post your other code and verify if the packets are being sent and received with a packet sniffer. – Diego C Nascimento Jan 21 '14 at 22:24
  • If you read my question you'd see that the phone actually IS the server. I'll do some clarification... – s3lph Jan 22 '14 at 15:13
  • Did you try `.setTimeToLive()` instead of `.setTimeout()`? I am not sure, though. – Siva Tumma Jan 26 '14 at 14:08
  • What do i have to supply as arugment to `setTimeToLive()`? – s3lph Jan 26 '14 at 16:39
  • Figured it out, but still not working – s3lph Jan 26 '14 at 20:28

2 Answers2

1

Make sure mhost is set to "224.0.0.115" not some machine name.

Make sure multicast is enabled on your router.

Ted Bigham
  • 4,237
  • 1
  • 26
  • 31
  • It is set to `224.0.0.115`. And how does the router affect the port opening on my machine? It doesn't work no matter what router (incl. phone via hotspot) i use – s3lph Jan 25 '14 at 14:36
  • 2
    Multicast requires cooperation of you network hardware. When you send a multicast message, you're not sending it to a machine, you're sending it to your switch or router, and it will then send it to everyone listening for it. That's why I'm a little concerned about the IP address you're using. It's not defined in this list http://en.wikipedia.org/wiki/Multicast_address. Have you tried using the "normal" multicast address 224.0.0.1 ? – Ted Bigham Jan 25 '14 at 22:49
  • Avahi (Zeroconf) also uses Multicast and is working without problems. So neither does my network card drop datagram packets nor does the router refuse them. Using `224.0.0.1` instead doesn't work. – s3lph Jan 26 '14 at 13:07
0
  1. If the host is multi-homed, you need to join the multicast group via all local interfaces, not just the default one, which is what you're doing at present.

  2. You could send the response back to the source address it came from, which is in the received datagram packet. That would also mean that the client doesn't need a MulticastSocket, only a DatagramSocket.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • If I understand point 2 correctly, you wnat me to let the SERVER connect to the source of the DatagramPacket. To point 1: How do I supply the interface? – s3lph Jan 23 '14 at 15:20
  • EDIT: I figured it out: `setNetworkInterface`. But the ports still stay closed. – s3lph Jan 23 '14 at 21:50