Check if a port is available on the specified host. This method first tries to bind to the port directly (most reliable), and falls back to connection test if bind fails due to permissions. Args: port: Port number to check host: Host address to check (default: 127.
(port: int, host: str = '127.0.0.1')
| 17 | |
| 18 | |
| 19 | def check_port_available(port: int, host: str = '127.0.0.1') -> bool: |
| 20 | """ |
| 21 | Check if a port is available on the specified host. |
| 22 | |
| 23 | This method first tries to bind to the port directly (most reliable), |
| 24 | and falls back to connection test if bind fails due to permissions. |
| 25 | |
| 26 | Args: |
| 27 | port: Port number to check |
| 28 | host: Host address to check (default: 127.0.0.1) |
| 29 | |
| 30 | Returns: |
| 31 | True if port is available, False if occupied |
| 32 | """ |
| 33 | # First try: bind to port directly (most reliable method) |
| 34 | try: |
| 35 | with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: |
| 36 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) |
| 37 | s.bind((host, port)) |
| 38 | return True # Bind successful, port is available |
| 39 | except OSError as e: |
| 40 | if e.errno == 98 or e.errno == 48: # Address already in use |
| 41 | return False # Port is occupied |
| 42 | except Exception as e: |
| 43 | logger.warning( |
| 44 | f'Bind test failed for port {port}, falling back to connection test: {e}' |
| 45 | ) |
| 46 | |
| 47 | # Second try: connection test (fallback method) |
| 48 | try: |
| 49 | with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: |
| 50 | s.settimeout(1) |
| 51 | result = s.connect_ex((host, port)) |
| 52 | return result != 0 # 0 means connection successful, port is occupied |
| 53 | except Exception as e: |
| 54 | logger.warning(f'Error checking port {port}: {e}') |
| 55 | return False # Be conservative: assume occupied if we can't check reliably |
| 56 | |
| 57 | |
| 58 | def find_available_port(start_port: int = 8888, |
no outgoing calls
no test coverage detected