採用對話框架構的 MFC 程序,監聽端口 56789。核心初始化流程封裝於 Init_net() 函數:
BOOL CServerDlg::Init_net() {
addrLen = sizeof(SOCKADDR_IN);
status = WSAStartup(MAKEWORD(1, 1), &Data);
// ...
memset(&serverSockAddr, 0, sizeof(serverSockAddr));
serverSockAddr.sin_port = htons(PORT);
serverSockAddr.sin_family = AF_INET;
serverSockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
// ...
status = bind(serverSocket, (LPSOCKADDR)&serverSockAddr, sizeof(serverSockAddr));
// ...
status = listen(serverSocket, 5);
// ...
return true;
}
點擊「RUN」按鈕啟動 Reg_Load() 進入無限循環監聽:
void CServerDlg::Reg_Load() {
while(1) {
CWinThread* hHandle;
clientSocket = accept(serverSocket, (LPSOCKADDR)&clientSockAddr, &addrLen); // 阻塞等待
hHandle = AfxBeginThread(talkToClient, (LPVOID)clientSocket); // 創建工作線程
// ...
}
}
每個客戶端連接對應一個工作線程 talkToClient,負責處理該用戶的註冊/登錄請求及數據庫交互。數據庫採用 Access (netuser.mdb),通過 ODBC 連接,簡化了部署與維護。
通信服務器監聽端口 56790,是系統的核心樞紐,大量運用共享數據結構與多線程技術實現高效轉發。
定義兩個關鍵結構體,並作為全局變量在線程間共享:
// 在線用戶基本信息
struct socket_info {
SOCKET s_client; // 用戶 Socket
u_long client_addr; // 用戶網絡地址
CString pet; // 用戶暱稱
CWinThread* thread; // 該用戶發送線程指針
};
// 待轉發訊息信息
struct send_info {
CString data; // 格式化後的訊息內容
CWinThread* thread; // 目標發送線程指針
};
// 全局共享變量
send_info info_data;
CList<socket_info, socket_info&> s_info;
運作機制:
socket_info 加入 s_info 鏈表。info_data,遍歷 s_info 比對目標暱稱,找到對應的發送線程指針。ResumeThread)該發送線程執行發送操作。此設計實現了「以空間換時間」的高效路由,避免了頻繁的鎖競爭與數據拷貝。