这是一个精练的客户端套接字类,类名、函数名和变量名均采用匈牙利命名法。小写的x表明个人姓氏首字母(谢欣伦),我的习惯而已,若有雷同,纯属巧合。函数
CxClientSocket的使用以下(以某个叫作CSomeClass的类的相关代码为例):this
1、声明客户端套接字对象实例。spa
CxClientSocket m_csRemoteHost;
2、设置客户端套接字事件通知方式。消息响应或回调函数,任选其一。客户端套接字事件有:缓冲区有数据可读取、与远程主机的链接被断开。指针
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(); }
3、链接远程主机。code
BOOL CSomeClass::ConnectToRemoteHost() { if (m_csRemoteHost.IsConnected()) m_csRemoteHost.DisConnect(); BOOL bRet = m_csRemoteHost.Connect(m_ipapRemoteHost.szAddr, m_ipapRemoteHost.nPort); return bRet; }
4、处理消息响应或函数回调。
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::OnSocketRead(WPARAM wParam) { if (m_csRemoteHost.GetSocket() == (SOCKET)wParam) { m_csRemoteHost.SelectEvent(FD_CLOSE); SOME_DATA_STRUCT data = {0}; if (m_csRemoteHost.Recv((LPBYTE)&data, sizeof(data))) {
//do something with data;
} m_csRemoteHost.SelectEvent(FD_READ | FD_CLOSE); } } void CSomeClass::OnSocketClose(WPARAM wParam) { if (m_csRemoteHost.GetSocket() == (SOCKET)wParam) { m_csRemoteHost.DisConnect(); char szDebug[MAX_PATH]; sprintf(szDebug, "%s disconnect.\n", m_szRemoteHostName); OutputDebugString(szDebug); GetParent()->PostMessage(WM_SOCKET_EVENT, (WPARAM)this, FD_CLOSE); } }
2.回调函数blog
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_csRemoteHost.SetWindowMessage(&msg, SocketProc);
5、断开与远程主机的链接。ip
void CSomeClass::OnDestroy() { CStatic::OnDestroy(); // TODO: Add your message handler code here TerminateWaitComm(); m_csRemoteHost.DisConnect(); m_ssLocalHost.DisListen(); m_usRemoteHost.Disbind(); }
至于客户端套接字数据发送,很简单:在须要处调用如下函数:ci
m_csRemoteHost.Send((LPBYTE)pData, sizeof(SOME_DATA_STRUCT));
精练的代码不须要过多解释,大家懂的。To be continued...
下载