| import socket | |
| import json | |
| import threading | |
| from .config import CONFIG | |
| class UDPDiscoveryServer: | |
| def __init__(self, log_callback, ip_provider): | |
| self.port = CONFIG.get("discovery_port", 8081) | |
| self.log = log_callback or (lambda msg, level="info": None) | |
| self.ip_provider = ip_provider | |
| self.socket = None | |
| self.running = False | |
| def start(self): | |
| if self.running: | |
| return | |
| try: | |
| self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
| self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |
| self.socket.bind(('', self.port)) | |
| self.running = True | |
| threading.Thread(target=self._listen, daemon=True).start() | |
| self.log(f"๐ UDP discovery listening on port {self.port}", "info") | |
| except OSError as e: | |
| self.log(f"โ Could not start UDP discovery: {e}", "error") | |
| def _listen(self): | |
| while self.running: | |
| try: | |
| data, addr = self.socket.recvfrom(1024) | |
| msg = data.decode().strip() | |
| if msg == "AIRMOUSE_DISCOVER": | |
| chosen_ip = self.ip_provider() | |
| response = json.dumps({ | |
| "type": "discovery_response", | |
| "port": CONFIG.get("port", 8080), | |
| "ip": chosen_ip | |
| }) | |
| self.socket.sendto(response.encode(), addr) | |
| self.log(f"๐ก Responded to {addr[0]} with {chosen_ip}", "info") | |
| except socket.timeout: | |
| continue | |
| except Exception as e: | |
| if self.running: | |
| self.log(f"โ ๏ธ UDP error: {e}", "warning") | |
| def stop(self): | |
| self.running = False | |
| if self.socket: | |
| self.socket.close() |
Xet Storage Details
- Size:
- 1.87 kB
- Xet hash:
- f8e909112ee5ec674bb49b96570546176a7e79f6357c97e556d7f2e5a0c6b477
ยท
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.