Bastien D
Bastien D

Reputation: 53

Sending broadcast in Python

I am trying to learn to code sockets (in Python 3), I am simply trying to send a broadcast from a server and receive it from a client.

My problem is that whenever I try to send the packets to 255.255.255.255, it seems nothing is actually sent. I tried to find the packets with wireshark but except on the loopback interface, I can't find any.

I can successfully send a message between the two computers when manually inputting the IP, and I also see the packets in wireshark.

Here's the code for the client

import socket


sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.bind(("0.0.0.0", 5005))
while True:
    # sock.sendto(bytes("hello", "utf-8"), ip_co)
    data, addr = sock.recvfrom(1024)
    print(data)

And here's the code for the server

import socket
from time import sleep

def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)  # UDP
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    #  sock.settimeout(2)
    while True:

        sock.sendto(bytes("test", "utf-8"), ("255.255.255.255", 5005))

        sleep(1)


main()

Sorry if the code is ugly, I am very new to sockets and to python.

Upvotes: 5

Views: 36735

Answers (2)

Tamir Adler
Tamir Adler

Reputation: 421

If you are here to just know how to send broadcast and the solution of Mario don't work for you, because you are getting list of ips as 127.0.1.1, so there is a simpler solution:

with socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) as sock:
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    sock.sendto(msg, ("255.255.255.255", 5005))

Notice that the disadvantage here is that it will not go throw all the network interfaces, like Mario solution, just the one per the OS IP table. So keep in mind...

Upvotes: 3

Mario Camilleri
Mario Camilleri

Reputation: 1557

The reason is that you are broadcasting on one interface and listening on another. See this answer UDP-Broadcast on all interfaces.

You need to broadcast on all interfaces, for example using the following (purely for demonstration) code. However, keep in mind that broadcasting over IP is a legacy feature which has been dropped from IPv6. Use multicasting instead.

import socket
from time import sleep

def main():
    interfaces = socket.getaddrinfo(host=socket.gethostname(), port=None, family=socket.AF_INET)
    allips = [ip[-1][0] for ip in interfaces]

    msg = b'hello world'
    while True:

        for ip in allips:
            print(f'sending on {ip}')
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)  # UDP
            sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
            sock.bind((ip,0))
            sock.sendto(msg, ("255.255.255.255", 5005))
            sock.close()

        sleep(2)


main()

Upvotes: 11

Related Questions