Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 690
Bastien D Avatar asked Aug 29 '26 14:08

Bastien D


2 Answers

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()
like image 150
Mario Camilleri Avatar answered Aug 31 '26 03:08

Mario Camilleri


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...

like image 33
Tamir Adler Avatar answered Aug 31 '26 05:08

Tamir Adler



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!