How do I set up a socket to join and receive on a UDP multicast?
I have tried the following on a windows 2000 machine...
====================================
import socket
s1 = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s1.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, '234.5.6.7')
s1.bind(('',6000))
while 1:
data = s1.recv(10000)
print data
====================================
It just HANGS at the s1.recv(10000). However, if I don't try to do a
multicast and just have server UDP to the regular IP, I receive the packets
just fine.
Now, when I take the above code to a Linux computer, I can't even run the
program cuz I get and error that says...
"Invalid argument" when it gets to line
s1.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, '234.5.6.7')
I really need to be able to receive multicast messages. Your help is most
appreciated!!!
Larry
> s1.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, '234.5.6.7')
The problem here is that IP_ADD_MEMBERSHIP requires a struct ip_mreq,
which is typically defined as
struct ip_mreq
{
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_interface; /* local IP address of interface */
};
So this is an 8-byte value. For imr_interface, you usually specify
INADDR_ANY, which is '\0\0\0\0', so you really need to use
group = socket.inet_aton('234.5.6.7') + '\0\0\0\0'
s1.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, group)
[Strictly speaking, you should use struct.pack to build the struct,
but the code above is just as portable, I assume]
HTH,
Martin
> The problem here is that IP_ADD_MEMBERSHIP requires a struct ip_mreq,
> which is typically defined as
>
> struct ip_mreq
> {
> struct in_addr imr_multiaddr; /* IP multicast address of group
*/
> struct in_addr imr_interface; /* local IP address of interface
*/
> };
>
> So this is an 8-byte value. For imr_interface, you usually specify
> INADDR_ANY, which is '\0\0\0\0', so you really need to use
>
> group = socket.inet_aton('234.5.6.7') + '\0\0\0\0'
> s1.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, group)
>
> [Strictly speaking, you should use struct.pack to build the struct,
> but the code above is just as portable, I assume]
I truly appreciate you taking time to respond, but I really don't understand
what you are trying to explain to me. Everything else in python seems so
easy, and creating a tcp socket and udp socket is so easy, just a few lines
of code. I am really surprised that there is no EASY way to join a group.
Now, your explanation SEEMS like all I need to do is make a few adjustments,
but the "struct" throws a loop at me cuz I never messed with that before.
If I really do just need an "adjustment" to the above code I posted, could
you repost my code with the corrections so I can see how it all comes
together!
Thanks,
Larry
if you do a search at Google in the groups archive you should find plenty of
examples on using IP multicast in Python
Some example code I found has been uploaded here:
http://www.tetrica.com/quickdry/python/
Steven
> I truly appreciate you taking time to respond, but I really don't understand
> what you are trying to explain to me. Everything else in python seems so
> easy, and creating a tcp socket and udp socket is so easy, just a few lines
> of code. I am really surprised that there is no EASY way to join a group.
But it is a fact. Python just exposes the socket API of the underlying
operating system. Please take a moment to read the Linux setsockopt(2)
man page. You notice that setsockopt takes a pointer and a length.
Python currently does not "know" what all those socket options
mean. It just exposes the bare setsockopt API to you. Now,
IP_ADD_MEMBERSHIP requires a C structure, so you have to give it a C
structure. For that, you need to understand what data to put into the
C structure, *and* you have to understand how the C compiler lays out
this structure in memory. Then you can construct a Python string that
has the same layout.
Sorry this is so complicated; if you feel it should be simplified in a
future version, feel free to propose specific patches, or write a PEP.
Regards,
Martin
Thanks Steven (Gee, I sound like that Dell commercial)...that link did the
trick for me!
Larry