From: "James W. Mills" Date: 2007-04-12T03:12:45+09:00 Subject: Missing packets in multicast receiver. Hello list. I need to use multicast in a project I am working on. I would like to have a multicast sender send a large amount of multicast data, and a multicast receiver receive it. I used the example I found here: http://onestepback.org/index.cgi/Tech/Ruby/MulticastingInRuby.red to get started. What I want initially is to be able to blast packets to a multicast group. I wrote a simple multicast sender that prints a message every (almost) MB of data it sends. I also wrote a simple receiver that does the same thing for every (almost) MB of data it receives. Here they are. Sender: ############################## require 'socket' MULTICAST_ADDR = "225.0.0.1" PORT= 1200 begin socket = UDPSocket.open socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, [1].pack('i')) data_source = File.open '/dev/zero' data_length = 0 loop do data = data_source.read(1024) data_length += data.length if (data_length % 102400) == 0 puts data_length end socket.send(data, 0, MULTICAST_ADDR, PORT) end ensure socket.close end ############################## Receiver: ############################## require 'socket' require 'ipaddr' MULTICAST_ADDR = "225.0.0.1" PORT = 1200 ip = IPAddr.new(MULTICAST_ADDR).hton + IPAddr.new("0.0.0.0").hton sock = UDPSocket.new sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ip) sock.bind(Socket::INADDR_ANY, PORT) start = Time.now data_length = 0 begin while true msg, info = sock.recvfrom(1024) data_length += msg.length if data_length % 102400 == 0 puts data_length end end ensure sock.close puts "Ran for #{Time.now - start}" end ############################## If you start the receiver, then start the sender, you will see that the numbers do not line up at all. The receiver gets one MB for every 10 or so MB that is sent. Now, please don't fillet me over the coals for this, but I have the receiver written in perl as well. The perl code does the same thing as the Ruby code was meant to. Here it is. ############################## use IO::Socket::Multicast; # create a new UDP socket ready to read datagrams on port 1100 my $s = IO::Socket::Multicast->new(LocalPort=>1200); # Add a multicast group $s->mcast_add('225.0.0.1'); # now receive some multicast data $data = ""; $t=0; while(true) { $s->recv($data,1024); $t += length $data; if($t % 102400 == 0) { warn "$t"; } } ############################## If you run the perl receiver against the Ruby sender, the programs print out the same messages, as expected. I am very curious to know what I am doing wrong with the Ruby receiver that is causing it to miss so much data. I suspect the line: sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ip) in the receiver might hold the answer, but so far nothing I have tried has made any difference. I find it interesting that it is using TCP instead of UDP/DGRAM, but I was unable to get it to work with IPPROTO_UDP... Help is very much appreciated! Thanks, ~james