Search code examples
pythonudpbroadcast

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.


Solution

  • 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()