IocpModeSvr.h: interface for the CIocpModeSvr class.

本文介绍了一个基于完成端口模型的网络服务器引擎CIocpModeSvr的设计与实现细节,包括初始化、发送消息等功能,并提供了多种发送消息的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// IocpModeSvr.h: interface for the CIocpModeSvr class.
//
//
#if !defined(AFX_IOCPMODESVR_H__46FFF420_23C3_4356_A88D_AEBDA61EA186__INCLUDED_)
#define AFX_IOCPMODESVR_H__46FFF420_23C3_4356_A88D_AEBDA61EA186__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif 
#include <list>
#include <afxtempl.h>
#include <winsock2.h>
#include <fstream>
#include <time.h>  
using namespace std;
#pragma  comment(lib,"ws2_32.lib")
#define MAX_BUFFER_SIZE 32768*2+64
/***************************************************************************************
文件名:IocpModeSvr.h
类名:CIocpModeSvr
类说明:本类是一个完成端口模型的网络服务器引擎
运行平台:WinNT3.5以上版本、Windows2000

输入接口说明:
    本类接收一个回调函数地址,该函数具有如下原型
         void _stdcall ProcessRecvData(unsigned long	sIP,
			                           SOCKET			sClient,
									   char *			pData,
									   unsigned long	DataLength);
    此回调函数用来接收从客户端发来的数据或者某客户端断开连接的通知(有始有终)。
		 sIP :       表示数据通知的客户端IP地址
		 sClient :   服务器用于和客户端通迅的套接字,
		      如果不是断开连接消息,则您可使用此参数调用SendMsg向客户端发送数据
		 Data :      本次操作的数据
		 DataLength :本次操作数据的数据长度
提示:如果pData==NULL 并且DataLength 则表示那是客户端断开连接的消息,请针对业务做处理吧。

输出接口说明:
		 引擎初始化函数,第一参为回调地址(必须正确填写),第二参为服务端口号
		 初始化成功返回真,否则返回假
         bool Init(ProcessRecvData* pProcessRecvData,unsigned long iSvrPort=SVRPORT);

		 引擎反初始化函数,请在程序退出时调用,或者在程序需要重新启动服务时调用
		 void UnInit();
以下在关于发送消息函数组的接口说明
         1、向目标IP客户端发送数据,
		    第一参为目标客户端IP,
			第二参为数据区地址,
			第三参为数据区长度
			成功"提交"返回真,否则返回假,
			那可能是因为客户端已经断开或者根本就没有连接。
		 bool SendMsg(LPCTSTR TargetIp,char * pData,unsigned long Length);

         2、向目标套接字发送数据
		    第一参为客户端套接字
			第二参为数据区地址
			第三参为数据区长度
			成功"提交"返回真,否则返回假
			那可能是因为客户端已经断开连接
			提示:此函数为不需要检索的发送数据函数,具有高效率的特性。
			      你可以在你的数据通知回调中以第二参的sClient直接填写于
				  第一参中发送数据,如果你在接收到数据时需要回传消息,请
				  使用此函数
			成功"提交"返回真,否则返回假
		 bool SendMsg(SOCKET sClient,char * pData,unsigned long Length);


         3、向所有连线客户端发送数据
		    发送数据到所有已经正确连线的客户端
			第一参为数据区地址
			第二参为数据区长度
			成功"提交"返回真,否则返回假
			大部分情况下都会返回真 ^_^
		 bool SendMsgToAll(char * pData,unsigned long Length);


		 4、向除了某个IP外的其它所有在线客户端发送数据
		    第一参为除外的IP
			第二参为数据区地址,
			第三参为数据区长度,
			成功"提交"返回真,否则返回假
			大部分情况下都会返回真
		 bool SendMsgToOther(LPCTSTR SourceIp,char* pData,unsigned long Length);


		 5、向除了某个Socket久的其它所有在线客户端发送数据
		    第一参为除外的Socket
			第二参为数据区地址
			第三参为数据区长度
			成功"提交"返回真,否则返回假
			大部分情况下都会返回真
		 bool SendMsgToOther(SOCKET ExceptSocket,char * pData,unsigned long Length);

附助函数组1
		1、const char * GetLocalIpAdd()
		   返回本地Ip地址,返回值为点分十进制的字符串
		2、unsigned short GetSvrPort()
		   返回服务使用的侦听端口号

附助函数助2
		1、bool DisConnectClient(LPCTSTR ClientIp);
		   切断参数中指定的IP的客户端的连接,成功返回真,否则返回假。
		2、bool DisConnectClient(SOCKET sClient);
		   切断参数中指定的客户机的连接,参数中指定了要切断了套接口。
		3、void DisConnectAll();
		   切断所有客户机的连接。
***************************************************************************************/
#define SVRPORT 10012				//服务端口
#define RECV_POSTED 0				//接收数据
#define SEND_POSTED 1				//发送数据

//单句柄数据
typedef struct _PER_HANDLE_DATA			
{
	unsigned long	IpAddr;		//IP地址
	SOCKET			sClient;	//套接字
	unsigned long   Port;
}PER_HANDLE_DATA, *LPPER_HANDLE_DATA;

/** 
1、WSABUF结构的原型:
typedef struct __WSABUF {
	u_long len;
	char FAR* buf;
} WSABUF, *LPWSABUF;

2、 OVERLAPPED原型:OVERLAPPED结构包含了用于异步(或重叠) 输入输出(I/O)的信息。
typedef struct _OVERLAPPED {
	ULONG_PTR Internal;		//保留,OS使用
	ULONG_PTR InternalHigh; //保留,OS使用 
	union{    
		struct{
			DWORD Offset;      
			DWORD OffsetHigh;    
		};
		PVOID Pointer;		//保留,OS使用
	};  
	HANDLE hEvent;
} OVERLAPPED, *LPOVERLAPPED;
*/

//IO操作数据
typedef struct _PER_IO_OPERATION_DATA	
{
	OVERLAPPED OverLapped;		//重叠结构
	WSABUF RecvDataBuf;			//接收数据缓冲区(长度、指针)
	WSABUF SendDataBuf;			//发送数据缓冲区(长度、指针)
	char RecvBuf[MAX_BUFFER_SIZE];	//接收缓冲区
	char SendBuf[MAX_BUFFER_SIZE];	//发送缓冲区
	bool OperType;				//IO操作类型表示
}PER_IO_OPERATION_DATA, *PPER_IO_OPERATION_DATA;

//回调处理数据函数原型   direction=0 是服务器向外发出数据  =1 是服务器收到数据
typedef void ProcessRecvData(unsigned long sIP,SOCKET sClient,unsigned short port,int direction,char * pData,unsigned long DataLength,DWORD userdata);
DWORD WINAPI ServerWorkerProc(LPVOID lParam);
DWORD WINAPI ListenProc(LPVOID lParam);
class CIocpModeSvr  
{
public:
	int m_bClosing;
	//构造函数和析构函数
	CIocpModeSvr();
	virtual ~CIocpModeSvr();
public:
	//引擎初始化
	bool Init(ProcessRecvData* pProcessRecvData,char *serverip,unsigned long iSvrPort=SVRPORT,DWORD userdata=NULL);
	bool StartServer(ProcessRecvData *pProcessRecvData,DWORD userdata=NULL); 
	//引擎反初始化
	void UnInit();
public:
	//用于发送消息的函数组
    bool SendMsg(LPCTSTR TargetIp,char * pData,unsigned long Length,bool bshowsend);
	bool SendMsg(SOCKET  sClient, char * pData,unsigned long Length,bool bshowsend);

	bool SendMsgToAll(char * pData,unsigned long Length,bool bshowsend);
	bool SendMsgToAll(char *pData,unsigned long Length,unsigned int us,byte times,byte delta,bool bshowsend);
    bool SendMsgToOther(LPCTSTR ExceptIp,   char * pData,unsigned long Length,bool bshowsend);
	bool SendMsgToOther(SOCKET ExceptSocket,char * pData,unsigned long Length,bool bshowsend);
public:
	//获得本地Ip地址
	const char * GetLocalIpAdd()
	{ 
		if(IsStart) return HostIpAddr.c_str();
		else return NULL;
	}
	//获得服务器使用的端口号
	unsigned short GetSvrPort()
	{
		if(IsStart) return m_SvrPort;
		else return 0;
	}

	void GetIpAndPort(char *ip,unsigned short &port)
	{
		if(IsStart)
		{
			memcpy(ip,HostIpAddr.c_str(),16);
			port=m_SvrPort;
		}
		else
		{
			ip=NULL;
			port=0;
		}
	}

	HANDLE m_hOneOkEvent;    //一台设备成功
	HANDLE m_hAllOkEvent;    //全部设备成功

	//用于断开连接的函数组
public:
	bool DisConnectClient(LPCTSTR ClientIp);
	bool DisConnectClient(SOCKET sClient);
	void DisConnectAll();
    void GetClientList(unsigned long *IPlist,int &count);
	CRITICAL_SECTION cInfoSection;	//客户信息临界保护量
	
	unsigned short m_SvrPort;		//服务端口记录

protected:
	int InitNetWork(char *serverip,unsigned int SvrPort=SVRPORT, std::string *pHostIpAddress=NULL);
	void WriteLogString(LPCTSTR strLog);
	ProcessRecvData* m_pProcessRecvData;
private:
	HANDLE		CompletionPort;		//完成句柄
	std::string HostIpAddr;			//主机IP
	CArray <PER_HANDLE_DATA,PER_HANDLE_DATA> ClientInfo;	//客户信息列表
	bool		IsStart;			//服务是否已经启动
	SOCKET		ListenSocket;		//侦听端口
	HANDLE		ListenThreadHandle;	//侦听线程句柄,用于反初始化时销毁侦听线程
	DWORD		m_dwUserData;		//用户数据
	friend DWORD WINAPI ServerWorkerProc(LPVOID lParam);
	friend DWORD WINAPI ListenProc(LPVOID lParam);

	//ofstream   fout;
};

#endif // !defined(AFX_IOCPMODESVR_H__46FFF420_23C3_4356_A88D_AEBDA61EA186__INCLUDED_)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值