| 326 | current = None |
| 327 | |
| 328 | def __init__( |
| 329 | self, |
| 330 | host, |
| 331 | port=9091, |
| 332 | port_end=9199, |
| 333 | is_proxy=False, |
| 334 | tracker_addr=None, |
| 335 | key="", |
| 336 | load_library=None, |
| 337 | custom_addr=None, |
| 338 | silent=False, |
| 339 | reuse_addr=True, |
| 340 | timeout=None, |
| 341 | ): |
| 342 | # start update |
| 343 | self.host = host |
| 344 | self.port = port |
| 345 | self.libs = [] |
| 346 | self.custom_addr = custom_addr |
| 347 | |
| 348 | if silent: |
| 349 | logger.setLevel(logging.ERROR) |
| 350 | |
| 351 | if not is_proxy: |
| 352 | sock = socket.socket(base.get_addr_family((host, port)), socket.SOCK_STREAM) |
| 353 | |
| 354 | # Never set socket SO_REUSEADDR on Windows. The SO_REUSEADDR flag allow reusing the |
| 355 | # inactivate TIME_WATI state sockets on POSIX, but on Windows it will allow two or more |
| 356 | # activate sockets to bind on the same address and port if they all set SO_REUSEADDR, |
| 357 | # and result in indeterminate behavior. |
| 358 | if reuse_addr and sys.platform != "win32": |
| 359 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) |
| 360 | if timeout is not None: |
| 361 | sock.settimeout(timeout) |
| 362 | self.port = None |
| 363 | for my_port in range(port, port_end): |
| 364 | try: |
| 365 | sock.bind((host, my_port)) |
| 366 | self.port = my_port |
| 367 | break |
| 368 | except OSError as sock_err: |
| 369 | if sock_err.errno in [errno.EADDRINUSE]: |
| 370 | continue |
| 371 | raise sock_err |
| 372 | if not self.port: |
| 373 | raise ValueError(f"cannot bind to any port in [{port}, {port_end})") |
| 374 | logger.info("bind to %s:%d", host, self.port) |
| 375 | sock.listen(1) |
| 376 | self.sock = sock |
| 377 | self.thread = threading.Thread( |
| 378 | target=_listen_loop, |
| 379 | args=(self.sock, self.port, key, tracker_addr, load_library, self.custom_addr), |
| 380 | ) |
| 381 | self.thread.start() |
| 382 | else: |
| 383 | self.thread = threading.Thread( |
| 384 | target=_connect_proxy_loop, args=((host, port), key, load_library) |
| 385 | ) |