3

I'm using the following code to send Hello, world! to a multicast group with Java.

InetSocketAddress sa = new InetSocketAddress("239.0.0.1", 12345);
MulticastSocket s = new MulticastSocket(sa);
s.setTimeToLive(255);
s.joinGroup(sa.getAddress());

byte[] sbuf = "Hello, world!".getBytes();
DatagramPacket sp = new DatagramPacket(sbuf, sbuf.length, sa);
s.send(sp);

byte[] rbuf = new byte[1024];
DatagramPacket rp = new DatagramPacket(rbuf, rbuf.length);
s.receive(rp);

System.out.format("Received \"%s\".\n", new String(rbuf));

s.leaveGroup(sa.getAddress());
s.close();

For some reason, the code always throws an exception like this:

java.io.Exception: Invalid argument
    at java.net.PlainDatagramSocketImpl.send(Native Method)
    at java.net.DatagramSocket.send(...)
    at ...

Why is this? How can I fix it?

ryyst
  • 9,563
  • 18
  • 70
  • 97

2 Answers2

-1

To get data:

            InetAddress group;
            int port;
            group = InetAddress.getByName("239.0.0.1");
            port = Integer.parseInt("12345");

            //create Multicast socket to to pretending group
            MulticastSocket s = new MulticastSocket(port);
            s.joinGroup(group);

while(running){

            s.receive(pkt);

            System.out.println();

            String msg_rec;

            msg_rec = new String(pkt.getData(), 0, pkt.getLength());


            System.out.println("(FROM:" + pkt.getAddress()+ ") "+ msg_rec);

            System.out.println();

        }

To send data:

String msgToSend = "Hello, world!";

            dgram = new DatagramPacket(msgToSend.getBytes(), msgToSend.length(), group ,port);
            s.send(dgram);  
DmitryK
  • 1,333
  • 1
  • 11
  • 18
  • Th best way to do it is: Create Multicast-socket, start new thread(with a flag to stop it) that keeps reading data from Multicast Socket and output it. Then create function with Message to Send parameter, that sends the pretending message. – DmitryK Dec 28 '12 at 22:18
  • 1
    Your solution is not completely equivalent, though. Afaik, creating the `MulticastSocket` like I did in the OP binds it to the group's IP. This becomes relevant when you have multiple sockets listening on the same port, but you don't want to receive all traffic on every socket. – ryyst Dec 29 '12 at 09:28
  • @ryyst A completely equivalent solution wouldn't work, would it? It would have the same problem that yours does. What happened when you tried it? – user207421 Dec 30 '12 at 01:14
  • Let me see if i get you correctly, you do not want to send the message to every socket that is listening on the same port? May i ask what is your goal? because from what i think that to reach your goal, it is easy if you program a server that will have the same behavior as multicast socket... – DmitryK Jan 01 '13 at 16:14
-1

You are calling send() on an unconnected DatagramSocket with a DatagramPacket that doesn't contain a destination address:port. So there is nowhere to send it to. If you mean to send to the multicast address, you need to say so, by doing either of he things mentioned in the first sentence. Joining the group doesn't do that: it only affects receiving.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • 1
    I pass the `sa` parameter when creating the `DatagramPacket`, which contains the destination. – ryyst Dec 29 '12 at 09:33
  • @ryyst Oops. What platform? Try binding it to a real local IP address, or null, instead of the multicast address. – user207421 Dec 29 '12 at 18:24
  • Are you sure about this? According to [this](http://stackoverflow.com/questions/10692956/what-does-it-mean-to-bind-a-multicast-udp-socket), binding works differently for TCP and UDP. I think I'm using it correctly. What's interesting is that it only fails when calling `send` and not immediately upon socket creation. – ryyst Dec 29 '12 at 21:46
  • @ryyst I'm certain you should try it. Binding to the multicast address doesn't even work at all on Windows. It's a grey area. Try it and let us know the result. – user207421 Dec 30 '12 at 07:08