CAsyncSocket类的应用

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_OnAccept			WM_USER+1000
#define WM_SOCKET_OnClose			WM_USER+1001
#define WM_SOCKET_OnConnect			WM_USER+1002
#define WM_SOCKET_OnOutOfBandData	WM_USER+1003
#define WM_SOCKET_OnReceive			WM_USER+1004
#define WM_SOCKET_OnSend			WM_USER+1005
class GMSocket : public CAsyncSocket
{
// Attributes
public:

// Operations
public:
	GMSocket();
	GMSocket(HWND hwnd);
	virtual ~GMSocket();

// Overrides
public:
	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

// Implementation
protected:
};

/

//{{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_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// GMSocket
GMSocket::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 0
BEGIN_MESSAGE_MAP(GMSocket, CAsyncSocket)
	//{{AFX_MSG_MAP(GMSocket)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0

/
// GMSocket member functions

void GMSocket::OnAccept(int nErrorCode) 
{
	// TODO: Add your specialized code here and/or call the base class
	if (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 class
	if (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 class
	if (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 class
	if (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 class
	if (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 );
}


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值