# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview RobotClient is a .NET 8.0 TCP client simulator for a robotic arm control system. It creates multiple concurrent TCP connections to a server, simulating robotic arm clients that can send/receive control commands and status messages. ## Build and Run Commands ```bash # Build the project dotnet build # Run with default settings (1 client, connects to 127.0.0.1:2000) dotnet run # Run with custom options (format: key=value) dotnet run -- count=5 host=192.168.1.100 serverport=3000 localport=50000 reconnect=false # Build Docker image docker build -t robot-client . # Run in Docker docker run -it robot-client ``` ### Command-Line Options | Option | Default | Description | |--------|---------|-------------| | `count` | 1 | Number of client connections to create | | `host` | 127.0.0.1 | Server host address | | `serverport` | 2000 | Server port | | `localport` | 62312 | Starting local port (each client uses localport + clientId) | | `reconnect` | true | Enable automatic reconnection | | `reconnectinterval` | 5000 | Reconnect delay in milliseconds | | `maxreconnect` | -1 | Max reconnect attempts (-1 = infinite) | ## Architecture The entire application is contained in `Program.cs` using C# top-level statements. The architecture follows a multi-client concurrent pattern: ### Core Components 1. **ClientOptions** (line 358-397): Configuration parser that processes command-line arguments into a strongly-typed options object. 2. **RunClientAsync** (line 23-50): Entry point for each client. Binds to a local port, establishes initial connection, spawns a background listener with reconnection logic, and sends initialization commands. 3. **ConnectAsync** (line 52-67): Low-level TCP connection using `Socket` with explicit local port binding. 4. **RunWithReconnectAsync** (line 69-134): Wrapper around the message listener that handles automatic reconnection with configurable limits and delays. 5. **ListenServerMessagesAsync** (line 181-234): Continuous receive loop that buffers incoming data and parses framed messages. Properly cleans up sockets on disconnect. 6. **TryReadFramedMessages** (line 236-293): Parses messages using `content` framing protocol. Handles partial messages and buffers incomplete data. Contains simulated robot commands: - `Pickbattery,1` → Simulates picking operation (5 seconds) - `Putbattery,1` → Simulates placing operation (5 seconds) 7. **SendLoopAsync** (line 295-356): Interactive console input loop allowing manual commands to specific clients using format `clientId:message` (e.g., `1:Status`). Type `exit` to quit. ### Initialization Sequence Each client sends these commands on connection/startup: 1. `Homed` → Wait 500ms 2. `Runmode,2` → Wait 500ms 3. `Armobject,0` → Wait 500ms 4. `Controlmode,1` ### Protocol All messages use the frame format: `message` - UTF-8 encoded - Message boundaries are explicit, allowing streaming - Invalid data before `` is discarded - Cache limits 10KB to prevent memory exhaustion ### Thread Safety - `ConcurrentDictionary` tracks active client connections - Each client runs its own background Task for receiving messages - Socket cleanup happens in `finally` blocks to prevent resource leaks