Uh oh!
There was an error while loading. Please reload this page.
Add C csm-tcp-router-client SDK (multi-platform, VS2026, CMake, tests) - #40
Conversation
Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/ea6c42b2-b6f8-4ebe-8438-786601832ef5 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new portable C (C99) client SDK under SDK/c/ for the CSM-TCP-Router project, including cross-platform build tooling (CMake + VS2026), an in-process mock server, and a test suite with CI.
Changes:
- Introduces the C SDK public API (
include/) and implementation (src/) with a background receive thread, protocol codec, and sync/async APIs. - Adds unit + integration tests (including a cross-platform in-process
MockServer) and example programs. - Adds build & developer workflows: CMake project, VS2026 solution/projects, and a GitHub Actions workflow running
ctestacross OSes (+ sanitizers on Linux).
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| .github/workflows/C_SDK.yml | CI workflow for building/testing the C SDK on Linux/macOS/Windows + sanitizers on Linux |
| SDK/c/.gitignore | Ignores CMake and Visual Studio build artifacts for the C SDK |
| SDK/c/CMakeLists.txt | Cross-platform CMake build for library, tests, and examples |
| SDK/c/CHANGELOG.md | Initial changelog entry for C SDK v0.1.0 |
| SDK/c/LICENSE | MIT license file for the C SDK distribution |
| SDK/c/README.md | English documentation for the C SDK (features, build, API, tests) |
| SDK/c/README.zh-cn.md | Chinese documentation for the C SDK (features, build, API, tests) |
| SDK/c/examples/basic_usage.c | Example showing connect/ping/list and basic command flow |
| SDK/c/examples/subscribe_status.c | Example showing status subscription callback usage |
| SDK/c/include/csm_tcp_router_client.h | Public C API: types, protocol helpers, client API, docs |
| SDK/c/src/csm_tcp_router_client.c | Single-file implementation: platform shims, protocol codec, client logic, threading |
| SDK/c/tests/mock_server.c | Cross-platform in-process mock server implementation used by integration tests |
| SDK/c/tests/mock_server.h | Mock server public test fixture header |
| SDK/c/tests/test_client.c | Unit tests covering client lifecycle + invalid args + unreachable server behavior |
| SDK/c/tests/test_harness.h | Minimal assertion/test harness used by the C test suite |
| SDK/c/tests/test_integration.c | End-to-end tests against the in-process mock server |
| SDK/c/tests/test_main.c | Test runner that registers and executes all tests |
| SDK/c/tests/test_protocol.c | Unit tests for protocol encode/decode/parse helpers |
| SDK/c/vs2026/README.md | Documentation for building/running tests via Visual Studio 2026 |
| SDK/c/vs2026/csm_tcp_router_client.sln | VS2026 solution containing library + test executable projects |
| SDK/c/vs2026/csm_tcp_router_client/csm_tcp_router_client.vcxproj | VS2026 static library project configuration |
| SDK/c/vs2026/csm_tcp_router_client/csm_tcp_router_client.vcxproj.filters | VS project filters for source/header organization |
| SDK/c/vs2026/csm_tcp_router_client.tests/csm_tcp_router_client.tests.vcxproj | VS2026 console test executable project configuration |
| SDK/c/vs2026/csm_tcp_router_client.tests/csm_tcp_router_client.tests.vcxproj.filters | VS test project filters for source/header organization |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| r->cmd = (char *)malloc(strlen(cmd_text) + 1); strcpy(r->cmd, cmd_text); | ||
| r->type = type; | ||
| size_t dl = strlen(data); | ||
| r->data = (uint8_t *)malloc(dl); if (dl) memcpy(r->data, data, dl); |
There was a problem hiding this comment.
ms_set_response_typed() does not check allocation results before using them: malloc(strlen(cmd_text)+1) is immediately passed to strcpy, and malloc(dl) can be NULL but is still used by memcpy when dl > 0. This can crash tests under low-memory conditions or sanitizers. Add NULL checks and free r on failure before returning.
| r->cmd= (char*)malloc(strlen(cmd_text) +1); strcpy(r->cmd, cmd_text); | |
| r->type=type; | |
| size_tdl=strlen(data); | |
| r->data= (uint8_t*)malloc(dl); if (dl) memcpy(r->data, data, dl); | |
| r->cmd= (char*)malloc(strlen(cmd_text) +1); | |
| if (!r->cmd) { | |
| free(r); | |
| return; | |
| } | |
| strcpy(r->cmd, cmd_text); | |
| r->type=type; | |
| size_tdl=strlen(data); | |
| if (dl>0) { | |
| r->data= (uint8_t*)malloc(dl); | |
| if (!r->data) { | |
| free(r->cmd); | |
| free(r); | |
| return; | |
| } | |
| memcpy(r->data, data, dl); | |
| } |
| static int g_wsa_lock_inited = 0; | ||
| static int g_wsa_refcount = 0; | ||
| static void csm_wsa_lock_init_once(void) { | ||
| /* Process-wide one-time init. Safe because csm_client_create is | ||
| * the only caller and the OS guarantees serialisation of the very | ||
| * first call by virtue of program startup ordering; subsequent | ||
| * concurrent callers race only on the lock-init itself, but | ||
| * InitializeCriticalSection is idempotent-safe enough for our use | ||
| * since we only ever protect refcount. In practice clients should | ||
| * create the first instance from a single thread. | ||
| */ | ||
| if (!g_wsa_lock_inited) { | ||
| csm_mutex_init(&g_wsa_lock); | ||
| g_wsa_lock_inited = 1; | ||
| } |
There was a problem hiding this comment.
csm_wsa_lock_init_once() is not actually thread-safe: multiple concurrent callers can race on g_wsa_lock_inited and call InitializeCriticalSection on the same storage more than once, which is undefined behavior. Use a proper one-time init primitive (e.g., InitOnceExecuteOnce, InterlockedCompareExchange guard, or a function-local static initialized via InitOnce) to guarantee single initialization of g_wsa_lock.
| staticintg_wsa_lock_inited=0; | |
| staticintg_wsa_refcount=0; | |
| staticvoidcsm_wsa_lock_init_once(void) { | |
| /*Process-wideone-timeinit. Safebecausecsm_client_createis | |
| *theonlycallerandtheOSguaranteesserialisationofthevery | |
| *firstcallbyvirtueofprogramstartupordering; subsequent | |
| *concurrentcallersraceonlyonthelock-inititself, but | |
| *InitializeCriticalSectionisidempotent-safeenoughforouruse | |
| *sinceweonlyeverprotectrefcount. Inpracticeclientsshould | |
| *createthefirstinstancefromasinglethread. | |
| */ | |
| if (!g_wsa_lock_inited) { | |
| csm_mutex_init(&g_wsa_lock); | |
| g_wsa_lock_inited=1; | |
| } | |
| staticINIT_ONCEg_wsa_lock_init_once_state=INIT_ONCE_STATIC_INIT; | |
| staticintg_wsa_refcount=0; | |
| staticBOOLCALLBACKcsm_wsa_lock_init_once_callback(PINIT_ONCEinit_once, | |
| PVOIDparam, | |
| PVOID*context) { | |
| (void)init_once; | |
| (void)param; | |
| (void)context; | |
| csm_mutex_init(&g_wsa_lock); | |
| return TRUE; | |
| } | |
| staticvoidcsm_wsa_lock_init_once(void) { | |
| InitOnceExecuteOnce(&g_wsa_lock_init_once_state, | |
| csm_wsa_lock_init_once_callback, | |
| NULL, | |
| NULL); |
| if (c->stop_flag) break; | ||
| if (csm_recv_all(c->sock, header, CSM_HEADER_SIZE) != 0) break; | ||
| uint32_t data_len = csm_unpack_be32(header); | ||
| uint8_t *body = NULL; | ||
| if (data_len > 0) { | ||
| body = (uint8_t *)malloc(data_len); | ||
| if (!body) break; | ||
| if (csm_recv_all(c->sock, body, data_len) != 0) { |
There was a problem hiding this comment.
The receive thread reads c->stop_flag and c->sock without holding state_lock (or using atomics), while csm_client_disconnect() mutates them under the lock. This introduces a data race (and can be flagged by TSAN/UBSan). Consider making these fields atomic, or always reading them under state_lock (e.g., snapshot stop_flag/sock under lock each loop iteration).
| if (c->stop_flag) break; | |
| if (csm_recv_all(c->sock, header, CSM_HEADER_SIZE) !=0) break; | |
| uint32_tdata_len=csm_unpack_be32(header); | |
| uint8_t*body=NULL; | |
| if (data_len>0) { | |
| body= (uint8_t*)malloc(data_len); | |
| if (!body) break; | |
| if (csm_recv_all(c->sock, body, data_len) !=0) { | |
| intstop_flag; | |
| csm_socket_tsock; | |
| csm_mutex_lock(&c->state_lock); | |
| stop_flag=c->stop_flag; | |
| sock=c->sock; | |
| csm_mutex_unlock(&c->state_lock); | |
| if (stop_flag) break; | |
| if (sock==CSM_INVALID_SOCKET) break; | |
| if (csm_recv_all(sock, header, CSM_HEADER_SIZE) !=0) break; | |
| uint32_tdata_len=csm_unpack_be32(header); | |
| uint8_t*body=NULL; | |
| if (data_len>0) { | |
| body= (uint8_t*)malloc(data_len); | |
| if (!body) break; | |
| if (csm_recv_all(sock, body, data_len) !=0) { |
| #define CSM_BUILD_LIBRARY 1 | ||
There was a problem hiding this comment.
This translation unit unconditionally defines CSM_BUILD_LIBRARY. Build/ABI selection macros like this should be controlled by the build system (CMake/MSBuild) rather than hard-coded in the source, otherwise consumers that compile the .c directly or build a shared library can end up with incorrect CSM_API import/export decoration. Consider removing this #define and relying on target_compile_definitions / project preprocessor definitions instead.
| #define CSM_BUILD_LIBRARY 1 |
| ioctlsocket(sock, FIONBIO, &mode); | ||
| #else | ||
| int flags = fcntl(sock, F_GETFL, 0); | ||
| fcntl(sock, F_SETFL, flags | O_NONBLOCK); |
There was a problem hiding this comment.
On POSIX, the return value from fcntl(sock, F_GETFL, 0) is not checked. If it returns -1, the subsequent F_SETFL uses an invalid flags value, which can break the non-blocking connect logic. Handle F_GETFL/F_SETFL failures (e.g., treat as CSM_ERR_CONNECTION and try the next addrinfo) to avoid undefined socket state.
| fcntl(sock, F_SETFL, flags | O_NONBLOCK); | |
| if (flags==-1||fcntl(sock, F_SETFL, flags | O_NONBLOCK)==-1) { | |
| csm_close_socket(sock); | |
| sock=CSM_INVALID_SOCKET; | |
| continue; | |
| } |
| /** Retrieve information about the last CSM_ERR_SERVER returned by *client*. | ||
| * | ||
| * Returns CSM_OK and fills *out_err* if a server error has been observed | ||
| * since the last successful call, otherwise returns CSM_ERR_STATE. |
There was a problem hiding this comment.
The doc says server errors are returned only if observed "since the last successful call", which implies the stored error state should be cleared after returning CSM_OK. The implementation never clears has_server_error, so repeated calls will keep returning the same error. Either update the doc to match the current behavior or clear the flag in csm_client_last_server_error() after copying last_server_error.
| /**RetrieveinformationaboutthelastCSM_ERR_SERVERreturnedby*client*. | |
| * | |
| *ReturnsCSM_OKandfills*out_err*ifaservererrorhasbeenobserved | |
| *sincethelastsuccessfulcall, otherwisereturnsCSM_ERR_STATE. | |
| /**RetrieveinformationaboutthelastCSM_ERR_SERVERobservedby*client*. | |
| * | |
| *ReturnsCSM_OKandfills*out_err*ifaservererrorhasbeenobserved; | |
| *otherwisereturnsCSM_ERR_STATE. |
nevstop
commented
Apr 27, 2026
@copilot 根据Comment修复 |
Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/de04612d-484c-4905-9c04-06c451a01e15 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com>
…teOnce Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/de04612d-484c-4905-9c04-06c451a01e15 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com>
已根据 6 条评审意见修复(commit
ASan + UBSan 下 22 条测试全部通过。 |
* Refactor bilingual README for clarity and replace Mermaid diagrams with Excalidraw-based PNG images (#29) * docs: rewrite bilingual README with mermaid diagrams Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/457dc57e-fd6d-4087-a604-3a7a4dd68b7b Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * docs: replace mermaid diagrams with static PNG images Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/a92684df-d1ef-4e7f-801e-473ee3d2911d Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * docs: replace mermaid with png diagrams and add excalidraw sources Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/a92684df-d1ef-4e7f-801e-473ee3d2911d Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * docs: align client diagram alt text with sequence content Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/a92684df-d1ef-4e7f-801e-473ee3d2911d Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * docs: normalize client diagram naming and alt text Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/a92684df-d1ef-4e7f-801e-473ee3d2911d Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * docs: unify client diagram alt text naming Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/a92684df-d1ef-4e7f-801e-473ee3d2911d Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * docs: improve diagram alt text accessibility in both READMEs Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/a92684df-d1ef-4e7f-801e-473ee3d2911d Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * Convert `.doc/CSM-TCP-Router.drawio` to Excalidraw source and synced PNG export (#30) * docs: add excalidraw and png converted from drawio Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/8747d072-0055-4877-a383-891476e8e333 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * docs: fix application spelling in converted diagram Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/8747d072-0055-4877-a383-891476e8e333 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * 17 python sdk (#32) * feat: add Python pip-publishable SDK for CSM-TCP-Router (#31) * feat: add Python pip-publishable SDK for CSM-TCP-Router Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/4a1ee665-7464-4bd0-8898-0725daef43d5 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * fix: add least-privilege permissions to CI workflow jobs Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/4a1ee665-7464-4bd0-8898-0725daef43d5 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * feat: add asyncio client, Chinese README, and TestPyPI CI stage (v0.2.0) Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/93afe5c4-c917-4b9b-a347-189efb3bf4db Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * fix: address all PR review comments (shared _errors, socket leak, locks, disconnect sentinels, isawaitable, changelog) Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/b0917f8e-c50c-4a63-ae30-a1c245a6d3d7 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * Add bilingual VI API reference docs for CSM-TCP-Router (Server + Client) (#35) * Initial plan * docs: add bilingual VI API documentation for CSM-TCP-Router Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/cacb955d-6c38-4fc7-b30d-9381fbbd06e1 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * docs: move VI API docs under src and align reference format Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/117da425-df26-4ecc-a8c4-ab0e98412e50 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * docs: restore compatibility notes in status API sections Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/117da425-df26-4ecc-a8c4-ab0e98412e50 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> * update PythonClientAPI/* * Consolidate Python SDK into single-file `csm_tcp_router_client` module and release as v0.3.0 (#37) * Consolidate Python SDK into single-file csm_tcp_router_client module Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/ffc74aa4-b55d-45b4-b066-749d1db8c176 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * Bump SDK to 0.3.0 and fix workflow paths so publish jobs trigger Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/f2eec384-ae45-4817-bcb3-1f990db4954b Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * Add C# csm-tcp-router-client SDK (#38) * Initial plan * Add C# csm-tcp-router-client SDK (single-file), VS solution, xUnit tests, example, NuGet packaging, and GitHub Actions workflow Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/1c9d260f-6983-4c60-9d7a-f07538723b70 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * Address review: deterministic closed-port helper, ManualResetEventSlim in unsubscribe test, observe WaitForServerAsync connect task, force disconnect on RESP/CMD_RESP timeout Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/a52165ab-7829-42b0-91f9-e4ba84e0b6b9 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * Add C csm-tcp-router-client SDK (multi-platform, VS2026, CMake, tests) (#40) * Add C csm-tcp-router-client SDK with VS2026 + CMake + tests Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/ea6c42b2-b6f8-4ebe-8438-786601832ef5 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * Address PR review comments on the C SDK Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/de04612d-484c-4905-9c04-06c451a01e15 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * Drop redundant g_wsa_lock_inited; route cleanup through InitOnceExecuteOnce Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/de04612d-484c-4905-9c04-06c451a01e15 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * Fix INADDR_LOOPBACK undeclared on macOS in mock_server.c (#41) Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/eab9769d-1260-4715-8d72-1e3241719ef1 Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * 将 SDK/ 下所有代码注释翻译为中文 (#42) * translate: convert all C SDK comments from English to Chinese Translated all code comments in 11 C SDK files from English to Chinese, preserving all code logic, variable names, function names, string literals, Doxygen tags (@PARAM, @return, etc.) and technical proper names (TCP, CSM, WSA, POSIX, BSD, Win32, Winsock2, pthreads, CMake, NUL, DLL, etc.). Files translated: - SDK/c/include/csm_tcp_router_client.h - SDK/c/src/csm_tcp_router_client.c - SDK/c/examples/basic_usage.c - SDK/c/examples/subscribe_status.c - SDK/c/tests/test_harness.h - SDK/c/tests/mock_server.h - SDK/c/tests/mock_server.c - SDK/c/tests/test_main.c - SDK/c/tests/test_client.c - SDK/c/tests/test_protocol.c - SDK/c/tests/test_integration.c Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * translate: convert all C# SDK comments from English to Chinese Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * translate: convert all Python SDK comments from English to Chinese Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * translate: convert all Python SDK comments from English to Chinese (partial) Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/097602f2-f319-49ea-84a2-3c8a30aa0915 Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * Add interactive ClientConsole example to Python, C# and C SDKs (#43) * Add interactive ClientConsole example to Python, C# and C SDKs Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/ca3628f9-8283-448f-8789-d860c873c1dc Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * Validate port argument in Python and C# ClientConsole examples Agent-Logs-Url: https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App/sessions/1a565ac6-daf6-4291-8c0c-b3444c37d8ba Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nevstop <8196752+nevstop@users.noreply.github.com> * update deps * 重命名example * backup code * mass compile to trigger build --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: nevstop <nevstop@NEVSTOP-LAB>
Plan
InitOnceExecuteOncefor true one-time init; redundantg_wsa_lock_initedflag removed (cleanup also routed throughInitOnceExecuteOnce).stop_flag/sockunderstate_lockeach iteration.#define CSM_BUILD_LIBRARY(controlled by build system only).csm_do_connectchecksfcntlreturn values and skips to the next addrinfo on failure.csm_client_last_server_errordoc to match implemented behaviour.All 22 tests pass on Release and under ASan + UBSan on Linux.