僅 5 個客戶端、C# 客戶端 + C++ 服務端,屬於**輕量級內部系統**。核心原則:**簡單優於複雜**,優先開發效率與可維護性。
| 模型 | 適用性 | 優點 | 缺點 |
|---|---|---|---|
| 多執行緒 (Thread-per-Client) | ✅ 最推薦 | 邏輯直觀、阻塞 API 簡單、5 連線資源極小 | 擴展性差 (百連線以上不適用) |
| 非阻塞 + Select/Poll (C++) | 可行 | 單執行緒高併發 | 邏輯複雜、易出錯、調試難 |
| IOCP / epoll / kqueue | 過度設計 | 極致效能 | 開發成本極高、非必要 |
| C# async/await + SocketAsyncEventArgs | 客戶端推薦 | 非阻塞 UI、程式碼同步風格 | 學習曲線 |
結論: 服務端用 **C++ std::thread + blocking socket** (或 boost::asio 同步 API);客戶端用 **C# async/await** 配合 TcpClient / NetworkStream。
TCP 是位元組流,無訊息邊界,必須自訂封包格式:
[Header: 4 bytes Length (big-endian)] [Body: Length bytes JSON/Protobuf]
// 或經典 TLV
[1 byte Type] [4 bytes Length] [Length bytes Value]
void handleClient(SOCKET sock) {
while (true) {
// 1. 讀 4 字節長度
uint32_t len = readExact(sock, 4); // 網路序轉主機序
if (len == 0 || len > MAX_PKG) break;
// 2. 讀 Body
vector<char> body(len);
readExact(sock, body.data(), len);
// 3. 解碼
Msg msg = decode(body);
// 4. 分派
switch (msg.cmd) {
case CMD_LOGIN: processLogin(msg); break;
case CMD_QUERY: processQuery(msg); break;
// ...
}
}
closesocket(sock);
}
PING,服務端 90 秒無收到視為斷線。SslStream (C#) / OpenSSL (C++)。Solution/
├─ Server (C++, CMake)
│ ├─ src/ (main, connection, handler, protocol)
│ └─ proto/ (.proto files)
├─ Client (C#, .NET 6+)
│ ├─ Models/ (DTO, Protobuf generated)
│ ├─ Services/ (NetworkService, AuthService)
│ └─ UI/ (WPF/WinForms/MAUI)
└─ Shared/ (protobuf definitions, build scripts)
從最簡單的多執行緒阻塞模型起步,驗證核心流程後再根據壓力測試結果優化,是小團隊交付的最佳路徑。