CxServerSocket的使用如下(以某個叫做CSomeClass的類的相關代碼為例):
一、聲明服務端套接字對象實例。
CxServerSocket m_ssLocalHost;
二、設置服務端套接字事件通知方式。消息響應或回調函數,任選其一。服務端套接字事件有:接收到客戶端的連接請求。
void CSomeClass::PreSubclassWindow() { // TODO: Add your specialized code here and/or call the base class HWND hwnd = GetSafeHwnd(); MSG msg = {hwnd, WM_SOCKET_EVENT}; m_usRemoteHost.SetWindowMessage(&msg); m_csRemoteHost.SetWindowMessage(&msg); m_ssLocalHost.SetWindowMessage(&msg); if (m_btCSMode == CSM_SERVER) ListenRemoteHost(); CStatic::PreSubclassWindow(); }
三、偵聽客戶端連接請求
BOOL CSomeClass::ListenRemoteHost() { char szIPAddr[MAX_IPV6]; if (CxSocket::GetLocalHost(szIPAddr)) return m_ssLocalHost.Listen(szIPAddr, NETPORT_NETWORK_COMM); else return FALSE; }
NETPORT_NETWORK_COMM是一個自定義的TCP端口值,只要不與公用端口沖突就行。
四、處理消息響應或函數回調。
1.消息響應
BEGIN_MESSAGE_MAP(CSomeClass, CStatic) //{{AFX_MSG_MAP(CSomeClass) ON_WM_DESTROY() //}}AFX_MSG_MAP ON_MESSAGE(WM_SOCKET_EVENT, OnSocketEvent) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSomeClass message handlers LRESULT CSomeClass::OnSocketEvent(WPARAM wParam, LPARAM lParam) { if (WSAGETSELECTERROR(lParam) != 0) return 1; int nEvent = WSAGETSELECTEVENT(lParam); switch (nEvent) { case FD_ACCEPT: OnSocketAccept(wParam); break; case FD_CLOSE: OnSocketClose(wParam); break; case FD_READ: OnSocketRead(wParam); break; default: break; } return 1; } void CSomeClass::OnSocketAccept(WPARAM wParam) { if ((SOCKET)wParam == m_ssLocalHost.GetSocket()) { CxClientSocket xcs; xcs =m_ssLocalHost.Accept(); if (xcs.GetSocket() != INVALID_SOCKET) { char szIPAddr[MAX_IPV6]; xcs.GetRemoteHost(szIPAddr); if (strcmp(szIPAddr, m_ipapRemoteHost.szAddr) == 0) m_csRemoteHost = xcs.GetSocket(); else { xcs.DisConnect(); CString str; str.Format("unknown socket %s disconnect.\n", szIPAddr); OutputDebugString(str); } } } }
2.回調函數
LRESULT CALLBACK CSomeClass::SocketProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT lRet = 0; CSomeClass* pThis = (CSomeClass*)hwnd; if (pThis != 0) lRet = pThis->OnSocketEvent(wParam, lParam); return lRet; }
注意,在使用回調函數時應設置服務端套接字事件通知方式為回調函數,並且設法把this指針傳入設置函數,方便在回調函數中調用成員函數。
MSG msg = {(HWND)this, WM_SOCKET_EVENT}; m_ssRemoteHost.SetWindowMessage(&msg, SocketProc);
五、停止偵聽客戶端連接請求
void CSomeClass::OnDestroy() { CStatic::OnDestroy(); // TODO: Add your message handler code here TerminateWaitComm(); m_csRemoteHost.DisConnect(); m_ssLocalHost.DisListen(); m_usRemoteHost.Disbind(); }
至於服務端如何與客戶端交換數據,很簡單:將服務端接受的客戶端連接賦給一個客戶端套接字對象實例,然后讓這個客戶端套接字對象實例在需要處完成數據交換就可以了(客戶端套接字類CxClientSocket如何使用?請查閱往期文章)。
CxClientSocket xcs; xcs = m_ssLocalHost.Accept(); // Save the expected socket and disconnect the unexpected socket m_csRemoteHost = xcs.GetSocket();
精練的代碼不需要過多解釋,你們懂的。To be continued...