6

I can't understand why if I create a socket in this way

from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.bind(("192.168.1.10",26000))
print s.recvfrom(4096)[0]

and I try to send to it a broadcast packet like this

from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
s.sendto("hey!", ("<broadcast>", 26000))

it doesn't work (it hangs on the recvfrom()) but if I try to bind it to "0.0.0.0" it receives the packet correctly.

I know that 0.0.0.0 means that every address on every interface will be listening on that port, but why binding directly to an address makes it don't receive the packet?

Operating system: OSX 10.9.2, Python version: 2.7.6

Even if I'm not running Linux, I tried binding the socket to the subnet broadcast address anyway, same results.

Kava
  • 93
  • 1
  • 2
  • 9
  • Which operating system do you use? Have you tried something like wireshark to have a look at which messages are sent over the interfaces when you broadcast? – User Apr 13 '14 at 13:23
  • What OS? If it's Linux it seems that it's not possible for non-root https://github.com/netty/netty/issues/576 You need to use 0.0.0.0 or just a separate socket – Konstantin Apr 13 '14 at 14:13
  • You may try to bind to the subnet broadcast address (for example 192.168.1.255, depending on your settings) as it's said here http://stackoverflow.com/questions/13666789/receiving-udp-broadcast-packets-on-linux – Konstantin Apr 13 '14 at 14:17
  • The `socket()` function accepts three arguments and I don't think the third one is optional in any case. – Pavel Šimerda Apr 13 '14 at 17:34
  • And be careful about the port numbers. They should always be enclosed in `htons()` so that you see the actual port number in the code and not a number with reversed byte order. – Pavel Šimerda Apr 13 '14 at 17:38
  • @Pavel: As described here, the socket function requires two arguments. https://docs.python.org/2/howto/sockets.html#creating-a-socket – Kava Apr 13 '14 at 18:18
  • @Kava: Wrong. The HOWTO is indeed not entirely correct here. The function accepts three arguments just as the POSIX C function does. Python allows all of them to be omitted (which I didn't realize at first). – Pavel Šimerda Apr 13 '14 at 18:38
  • See https://docs.python.org/2/library/socket.html – although I wouldn't agree that leaving out the protocol is a good idea for AF_INET/AF_INET6. – Pavel Šimerda Apr 13 '14 at 18:40

2 Answers2

3

If the operating system is Linux then try to bind socket to the subnet broadcast address. For example, if your ifconfig settings are inet addr:192.168.0.62 Bcast:192.168.0.255 Mask:255.255.255.0then bind your receiver socket to 192.168.0.255. On Linux you won't be able to use your regular IP address

There is a previous discussion on the topic here

Community
  • 1
  • 1
Konstantin
  • 2,937
  • 10
  • 41
  • 58
1

In order to Listen to Broadcast packets you need to use the following.

sock.bind(("<broadcast>", port_num))
or
sock.bind(("", port_num))
Mahadev
  • 63
  • 1
  • 6