CAsyncSocket类的应用

来源:互联网 发布:sketchbook mac 破解 编辑:程序博客网 时间:2024/05/19 17:26

CAsyncSocket介绍:它是一个异步非阻塞Socket封装类。它的工作原理是建立在MFC消息系统上,收到一个消息后会回调一个相应的函数。

一、原理分析

1、一般情况是要新建一类然后继承它,这样才可以重载它的一些函数。

2、服务端和客户端都用Create来新建一个Socket,不同的是服务端要设置IP和端口,客户端新建时只设置IP。

3、服务端一般不用Bind,直接Listen就可以了。当服务端进入监听后,客户端向服务端发一个Connect就可以了。注意IP地址和端口,特别是本机。

4、服务端收到Connect后会响应OnAccept函数(它里面怎样写见后面),批准客户端连接用Accept。

5、客户端收到Accept会响应OnConnect函数。之后服务端和客户端就会进入消息等待状态。

6、一方的Send会激活对方的OnReceive。

7、当数据未完全发送或接收时会响应OnSend或OnReceive。

8、关闭时会激活OnClose。

二、与窗口类的互动

当响应OnReceive后,就可以在OnReceive里面用Receive接收数据。但问题来了,怎样把收到的数据传给窗口类呢(如CDialog或CView)?我的解决方法是用自定义消息,在类里建一个句柄变量,构建的时候让它指向窗口类的句柄。在响应OnReceive时,用SendMessage向句柄发一个自定义消息。然后在窗口类里响应这个自定义消息就可以了。

PS:自定义消息

 

三、源码

头文件:

#if !defined(AFX_GMSOCKET_H__84048A8F_A38B_4107_9811_F279292BA3B3__INCLUDED_)#define AFX_GMSOCKET_H__84048A8F_A38B_4107_9811_F279292BA3B3__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000// GMSocket.h : header file///////////////////////////////////////////////////////////////////////////////// GMSocket command target#define WM_SOCKET_OnAcceptWM_USER+1000#define WM_SOCKET_OnCloseWM_USER+1001#define WM_SOCKET_OnConnectWM_USER+1002#define WM_SOCKET_OnOutOfBandDataWM_USER+1003#define WM_SOCKET_OnReceiveWM_USER+1004#define WM_SOCKET_OnSendWM_USER+1005class GMSocket : public CAsyncSocket{// Attributespublic:// Operationspublic:GMSocket();GMSocket(HWND hwnd);virtual ~GMSocket();// Overridespublic:void ShowErrorMsg(int errorcode);HWND SetTargetHWND(HWND hwnd);HWND m_TargetWnd;// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(GMSocket)public:virtual void OnAccept(int nErrorCode);virtual void OnClose(int nErrorCode);virtual void OnConnect(int nErrorCode);virtual void OnOutOfBandData(int nErrorCode);virtual void OnReceive(int nErrorCode);virtual void OnSend(int nErrorCode);//}}AFX_VIRTUAL// Generated message map functions//{{AFX_MSG(GMSocket)// NOTE - the ClassWizard will add and remove member functions here.//}}AFX_MSG// Implementationprotected:};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_GMSOCKET_H__84048A8F_A38B_4107_9811_F279292BA3B3__INCLUDED_)


 

CPP文件:

// GMSocket.cpp : implementation file//#include "stdafx.h"//#include <windows.h>#include "MyAsyncSocket.h"#include "GMSocket.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// GMSocketGMSocket::GMSocket(){m_TargetWnd=0;}GMSocket::GMSocket(HWND hwnd){m_TargetWnd=hwnd;}GMSocket::~GMSocket(){}// Do not edit the following lines, which are needed by ClassWizard.#if 0BEGIN_MESSAGE_MAP(GMSocket, CAsyncSocket)//{{AFX_MSG_MAP(GMSocket)//}}AFX_MSG_MAPEND_MESSAGE_MAP()#endif// 0/////////////////////////////////////////////////////////////////////////////// GMSocket member functionsvoid GMSocket::OnAccept(int nErrorCode) {// TODO: Add your specialized code here and/or call the base classif (nErrorCode==0){SendMessage(m_TargetWnd,WM_SOCKET_OnAccept,0,0);}else{ShowErrorMsg(GetLastError());}CAsyncSocket::OnAccept(nErrorCode);}void GMSocket::OnClose(int nErrorCode) {// TODO: Add your specialized code here and/or call the base classif (nErrorCode==0){SendMessage(m_TargetWnd,WM_SOCKET_OnClose,0,0);}else{ShowErrorMsg(GetLastError());}CAsyncSocket::OnClose(nErrorCode);}void GMSocket::OnConnect(int nErrorCode) {//OnConnect(WPARAM wParam, LPARAM lParam)// TODO: Add your specialized code here and/or call the base classif (nErrorCode==0){SendMessage(m_TargetWnd,WM_SOCKET_OnConnect,0,0);}else{ShowErrorMsg(GetLastError());}CAsyncSocket::OnConnect(nErrorCode);}void GMSocket::OnOutOfBandData(int nErrorCode) {// TODO: Add your specialized code here and/or call the base classif (nErrorCode==0){SendMessage(m_TargetWnd,WM_SOCKET_OnOutOfBandData,0,0);}else{ShowErrorMsg(GetLastError());}CAsyncSocket::OnOutOfBandData(nErrorCode);}void GMSocket::OnReceive(int nErrorCode) {//OnReceive(WPARAM wParam, LPARAM lParam)if (nErrorCode==0){SendMessage(m_TargetWnd,WM_SOCKET_OnReceive,0,0);}else{ShowErrorMsg(GetLastError());}CAsyncSocket::OnReceive(nErrorCode);}void GMSocket::OnSend(int nErrorCode) {// TODO: Add your specialized code here and/or call the base classif (nErrorCode==0){SendMessage(m_TargetWnd,WM_SOCKET_OnSend,0,0);}else{ShowErrorMsg(GetLastError());}CAsyncSocket::OnSend(nErrorCode);}HWND GMSocket::SetTargetHWND(HWND hwnd){m_TargetWnd=hwnd;return m_TargetWnd;}void GMSocket::ShowErrorMsg(int errorcode){LPVOID lpMsgBuf;FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,errorcode,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language(LPTSTR) &lpMsgBuf,0,NULL );MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );// Free the buffer.LocalFree( lpMsgBuf );}


 

原创粉丝点击