From b33c3b88497e17d64dcdc692e6531e18434ad793 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 29 Apr 2026 15:57:31 -0700 Subject: [PATCH] Add some test scripts for ws and move to testing/ --- udp_client.py => testing/udp_client.py | 0 udp_server.py => testing/udp_server.py | 0 testing/ws_client.py | 60 ++++++++++++++++++++++++++ testing/ws_server.py | 49 +++++++++++++++++++++ 4 files changed, 109 insertions(+) rename udp_client.py => testing/udp_client.py (100%) rename udp_server.py => testing/udp_server.py (100%) create mode 100644 testing/ws_client.py create mode 100644 testing/ws_server.py diff --git a/udp_client.py b/testing/udp_client.py similarity index 100% rename from udp_client.py rename to testing/udp_client.py diff --git a/udp_server.py b/testing/udp_server.py similarity index 100% rename from udp_server.py rename to testing/udp_server.py diff --git a/testing/ws_client.py b/testing/ws_client.py new file mode 100644 index 0000000..5aa5c72 --- /dev/null +++ b/testing/ws_client.py @@ -0,0 +1,60 @@ +import asyncio +import sys +import websockets + +# Argument parsing: Check if HOST and PORT are provided +if len(sys.argv) < 3 or len(sys.argv) > 4: + print("Usage: python ws_client.py [ws|wss]") + # Example: python ws_client.py 127.0.0.1 8765 + # Example: python ws_client.py 127.0.0.1 8765 wss + sys.exit(1) + +HOST = sys.argv[1] +try: + PORT = int(sys.argv[2]) +except ValueError: + print("Error: HOST_PORT must be an integer.") + sys.exit(1) + +if len(sys.argv) == 4: + SCHEME = sys.argv[3].lower() + if SCHEME not in ("ws", "wss"): + print("Error: scheme must be 'ws' or 'wss'.") + sys.exit(1) +else: + SCHEME = "ws" + +URI = f"{SCHEME}://{HOST}:{PORT}" + +# The message to send to the server +MESSAGE = "Hello WebSocket Server! How are you?" + + +async def main(): + print(f"Connecting to {URI}...") + + try: + async with websockets.connect(URI) as websocket: + print(f"Connected to server.") + print(f"Sending message: '{MESSAGE}'") + + await websocket.send(MESSAGE) + + response = await websocket.recv() + + print("-" * 30) + print(f"Received response from server:") + print(f"-> Data: '{response}'") + + except ConnectionRefusedError: + print(f"Error: Connection to {URI} was refused. Is the server running?") + except websockets.exceptions.InvalidMessage as e: + print(f"Error: Server did not respond with a valid WebSocket handshake: {e}") + except Exception as e: + print(f"Error during communication: {e}") + + print("-" * 30) + print("Client finished.") + + +asyncio.run(main()) diff --git a/testing/ws_server.py b/testing/ws_server.py new file mode 100644 index 0000000..2e2880d --- /dev/null +++ b/testing/ws_server.py @@ -0,0 +1,49 @@ +import asyncio +import sys +import websockets + +# Optionally take in a positional arg for the port +if len(sys.argv) > 1: + try: + PORT = int(sys.argv[1]) + except ValueError: + print("Invalid port number. Using default port 8765.") + PORT = 8765 +else: + PORT = 8765 + +# Define the server host +HOST = "0.0.0.0" + + +async def handle_client(websocket): + client_address = websocket.remote_address + print(f"Client connected: {client_address[0]}:{client_address[1]}") + + try: + async for message in websocket: + print("-" * 30) + print(f"Received message from {client_address[0]}:{client_address[1]}:") + print(f"-> Data: '{message}'") + + response = f"Hello client! Server received: '{message.upper()}'" + + await websocket.send(response) + print(f"Sent response back to client.") + + except websockets.exceptions.ConnectionClosedOK: + print(f"Client {client_address[0]}:{client_address[1]} disconnected cleanly.") + except websockets.exceptions.ConnectionClosedError as e: + print(f"Client {client_address[0]}:{client_address[1]} disconnected with error: {e}") + + +async def main(): + print(f"WebSocket Server listening on {HOST}:{PORT}") + async with websockets.serve(handle_client, HOST, PORT): + await asyncio.Future() # Run forever + + +try: + asyncio.run(main()) +except KeyboardInterrupt: + print("\nServer stopped.")