4

I just started with networking and am writing a very simple code for multicasting. I am still not sure about the different interfaces. Some examples used "0.0.0.0" while others have used "127.0.0.1".

Code for Server

import socket
import sys
import time

ANY = socket.gethostbyname('localhost')
S_PORT = 1501
M_ADDR = "224.168.2.9"
M_PORT = 1600

sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEPORT,1)
sock.bind((ANY,S_PORT))
sock.setsockopt(socket.IPPROTO_IP,socket.IP_MULTICAST_TTL,255)

while 1:
    message = raw_input("Enter message: ")
    sock.sendto(message,(M_ADDR,M_PORT))
    if message == "exit":
        break
sock.close()

Code for Client

import socket
import time
import sys

ANY = socket.gethostbyname('localhost')
M_ADDR = "224.168.2.9"
M_PORT = 1600
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEPORT,1)
sock.bind((ANY,M_PORT))
sock.setsockopt(socket.IPPROTO_IP,socket.IP_MULTICAST_TTL,255)
status = sock.setsockopt(socket.IPPROTO_IP,socket.IP_ADD_MEMBERSHIP,socket.inet_aton(M_ADDR) + socket.inet_aton(ANY))

while 1:
    data,addr = sock.recvfrom(1024)
    print "Received message from " + str(addr) + " : " + data
    if data == "exit":
        break
sock.close()

The Client code runs properly and is waiting to receive message on the socket. But the Code Server crashes as soon as I enter any message.

Traceback (most recent call last):
  File "multicast_server.py", line 17, in <module>
    sock.sendto(message,(M_ADDR,M_PORT))
socket.error: [Errno 49] Can't assign requested address

What is causing this issue ? The above code works if I use ANY = "0.0.0.0". Why is that ? What changes ?

Kyuubi
  • 1,228
  • 3
  • 18
  • 32
  • 1
    Are you sure you wanted `SO_REUSEPORT` but not `SO_REUSEADDR` here? ([This answer](http://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t) explains what they mean on each platform.) – abarnert Nov 05 '13 at 20:37
  • Yes, I am using a MAC OSX which requires `SO_REUSEPORT`. The link is helpful, as I was confused why the difference! – Kyuubi Nov 07 '13 at 14:45

3 Answers3

5

In IPv4, 0.0.0.0 is a special address, aka INADDR_ANY, that means "bind every possible address on every interface".

So, the multicast network at 224.168.2.9, if it's reachable at all, will certainly be reachable from a socket bound to 0.0.0.0.

Meanwhile, 127.0.0.1 is a special address, aka INADDR_LOOPBACK, that means "bind localhost only on the loopback device". There's no way to reach anything but the local host itself on that socket. In particular, you can't reach your multicast network. Whether you get an ENETUNREACH, ENETDOWN, or EADDRNOTAVAIL is platform-specific, but whether it works is not—it can't possibly work.

If you want to test multicasting without testing across multiple computers, you will need to set up a loopback network with more than one address, so you can bind the client, the server, and the multicast group all to different addresses within that network.

abarnert
  • 354,177
  • 51
  • 601
  • 671
1

When you use "0.0.0.0" or "" for networking in python, it opens up to any IP inbound. For your case, I would use "0.0.0.0" or "127.0.0.1" (if you are not comfortable opening up to the world.)

andrewgrz
  • 435
  • 3
  • 6
-5

get your device ip address ubuntu: ifcongfig

choose the ip address from any ethernet ,loop, wlan replace M_ADDR with that ip address