C# Socket Server Application Guide
C# Socket Server Application Guide
The 'timer1_Tick' method updates the current time display every second and handles mode 3 operations. If mode 3 is active ('isMode3Active' is true) and the application is not in manual mode, it checks if the current hour has changed since the last tick. If so, it calls 'SendMode3CommandByTime' to send appropriate commands ('C' for day and 'B' for night) based on the new hour. This allows the application to automate actions based on the time of day while in mode 3.
Commands are sent in response to user actions like button clicks: Button 1 sends 'A', button 2 sends 'B', button 3 activates mode 3 (sending 'C' or 'B' based on time), button 6 sets manual mode (sending 'M'), and button 7 sets interface mode (sending 'G'). The IP address and port are initially set in the 'Form1_Load' method, where text boxes for IP parts and port ('textBox8' to 'textBox12') are populated with default values like "192.168.0.125" for IP and "8000" for the port.
The application distinguishes between different modes using boolean flags. The 'isManualMode' flag indicates whether the application is in manual mode, while 'isMode3Active' indicates if mode 3 is active. In manual mode, triggered by button 6, the command 'M' is sent. In mode 3, activated by button 3, time-based commands are sent using 'SendMode3CommandByTime', which sends 'C' during daytime (5 AM - 10 PM) and 'B' otherwise. Buttons 1 and 2 send commands 'A' and 'B' respectively, deactivating mode 3. Button 7 switches back to interface mode with the command 'G'.
The application uses color-coded feedback and text boxes to represent connection status. When awaiting a connection, 'textBox1' turns yellow with the text “Waiting for device to connect...”. Upon a successful connection, it changes to lime green with the client's remote endpoint address displayed. If disconnected, it turns red with the text “Disconnected”. Additionally, different commands trigger related images to display on 'pictureBox2' corresponding to signals ('R', 'Y', 'G') received from the client.
The application uses threading for handling server connections (via 'AcceptThread') and receiving data from the client ('Receive' thread). Multithreading is crucial because it allows the application to manage network I/O operations without freezing the UI. This separation ensures that the user interface remains responsive while the application waits for client connections or processes incoming data, providing a smooth user experience.
The application handles errors while setting up the server when the port is invalid or already in use. If the port value entered is not a valid integer, a message box shows 'Port không hợp lệ!' (Invalid port!). If the port is already in use, it displays 'Port đang được sử dụng hoặc chưa giải phóng. Vui lòng chọn port khác.' (Port is in use or not released. Please choose another port.). These messages are shown using MessageBox.Show with error icons and appropriate text.
Without controlling cross-thread operations, potential issues like runtime exceptions could arise, especially when a background thread attempts to update UI components. Such cross-thread operations are unsafe and can result in inconsistent UI states and application crashes. The application foresees this by disabling cross-thread checks with 'Control.CheckForIllegalCrossThreadCalls = false', and also uses 'Invoke' to update UI components from non-UI threads safely. This approach ensures that UI updates happen on the UI thread, maintaining application stability and performance.
Closing the server or client sockets terminates the connection, indicated by changes in the UI (e.g., connection status changes to red and text to 'Disconnected'). The application ensures safe termination by first checking if the sockets are not null and then attempting to close them within try-catch blocks to handle potential exceptions gracefully. This prevents runtime crashes and ensures the program can restart the server safely if needed. Button states and input fields are appropriately toggled post-disconnection.
The application manages socket connections by using separate threads for accepting and receiving data. When button 4 is clicked, the server socket is initialized and set to listen for connections. Thread 'AcceptThread' is then started to manage the client connection, updating the UI with connection status. If successful, a new thread 'Receive' handles incoming data from the client. If the server or client needs to be closed, as managed by button 5, the respective sockets are closed properly and UI controls are reset.
The application includes user-friendly input handling by checking the validity of the port using 'int.TryParse' before attempting to use it for socket binding. If invalid, it immediately notifies the user with an error message via a MessageBox. Further, IP input fields are locked when the server is binding to a port, preventing alterations during critical operations, and re-enabled upon disconnection, ensuring that users can make changes only when applicable.