-
-
Save yiwenlu66/4f785d4546057b49b56c to your computer and use it in GitHub Desktop.
import asyncio | |
import socket | |
from string import ascii_letters | |
import random | |
class BroadcastProtocol: | |
def __init__(self, loop): | |
self.loop = loop | |
def connection_made(self, transport): | |
print('started') | |
self.transport = transport | |
sock = transport.get_extra_info("socket") | |
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) | |
self.broadcast() | |
def datagram_received(self, data, addr): | |
print('data received:', data, addr) | |
def broadcast(self): | |
string = ''.join([random.choice(ascii_letters) for _ in range(5)]) | |
print('sending:', string) | |
self.transport.sendto(string.encode(), ('192.168.1.255', 9000)) | |
self.loop.call_later(5, self.broadcast) | |
loop = asyncio.get_event_loop() | |
coro = loop.create_datagram_endpoint( | |
lambda: BroadcastProtocol(loop), local_addr=('0.0.0.0', 9000)) | |
loop.run_until_complete(coro) | |
loop.run_forever() | |
loop.close() |
If anyone else finds themselves using this as an example, please read the following from https://docs.python.org/3/library/asyncio-eventloop.html
Note The parameter reuse_address is no longer supported, as using SO_REUSEADDR poses a significant security concern for UDP. Explicitly passing reuse_address=True will raise an exception.
When multiple processes with differing UIDs assign sockets to an identical UDP socket address with SO_REUSEADDR, incoming packets can become randomly distributed among the sockets.
For supported platforms, reuse_port can be used as a replacement for similar functionality. With reuse_port, SO_REUSEPORT is used instead, which specifically prevents processes with differing UIDs from assigning sockets to the same socket address.
Do note that binding to '0.0.0.0' and then broadcasting to '192.168.1.255' is a bit of a cheat.
The user should be binding to their local IP address ('192.168.1.123' for example) not all local adapters as in your code example. The broadcast would likely be invalid on other adapters on a multi adapter system.
My small code improvement allows for both to be specified (and changed) at the same place.