// IOCPServer.h: interface for the CIOCPServer class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_IOCPSERVER_H__1EC64F02_5939_46BF_B121_DEDD88DB2D1B__INCLUDED_)
#define AFX_IOCPSERVER_H__1EC64F02_5939_46BF_B121_DEDD88DB2D1B__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define BUFSIZE 1024
#pragma comment(lib, "Ws2_32.lib")
#include
#include
#include
#include "buffer.h"
#define PRINTDEBUG(a) PrintError(#a,__FILE__,__LINE__,GetLastError())
__inline int PrintError(LPSTR linedesc, LPSTR filename, int lineno, DWORD errnum)
{
LPSTR lpBuffer;
char errbuf[256];
DWORD numread;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
errnum,
LANG_NEUTRAL,
(LPTSTR)&lpBuffer,
0,
NULL );
wsprintf(errbuf, "\nThe following call failed at line %d in %s:\n\n"
" %s\n\nReason: %s\n", lineno, filename, linedesc, lpBuffer);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), errbuf, strlen(errbuf), &numread, FALSE );
return errnum;
}
//定义操作类型
enum IOType
{
OP_IOInitialize,
OP_IORead,
OP_IOWrite,
OP_IOIdle
};
//定义completion key
typedef struct _CLIENTCONTEXT
{
SOCKETm_Socket;
CHARm_ip[32];
UINTm_nPort;
//存储接/发送数据的缓冲区
CBufferm_ReadBuffer;
CBufferm_WriteBuffer;
//winsock取得数据的缓冲区
WSABUFm_wsaInBuffer;
CHARm_byInBuffer[BUFSIZE];
//winsock发送数据的缓冲区,发送得数据就放在m_WriteBuffer
WSABUFm_wsaOutBuffer;
//为了防止写数据覆盖发生,设定此事件
HANDLEm_hWriteComplete;
} CLIENTCONTEXT, *LPCLIENTCONTEXT;
typedef struct _OVERLAPPEDPLUS
{
WSAOVERLAPPED ol;
//操作类型
IOType opCode;
} OVERLAPPEDPLUS, *LPOVERLAPPEDPLUS;
class CIOCPServer
{
public:
CIOCPServer();
virtual ~CIOCPServer();
void Accept();
BOOL Initialize(DWORD conns, int port);
//绑定在端口上工作线程
static DWORD WINAPI CompletionWorkerThread( void * lpParam);
protected:
//处理消息
virtual void ProcessReceiveData(LPCLIENTCONTEXT lpContext, CBuffer &buffer) = 0;
//用户退出,或者连接中断,返回TRUE:已经处理过该对出事件,FALSE,没有处理过该退出事件
//子类函数必须写
virtual BOOL ClientExit(LPCLIENTCONTEXT lpContext) = 0 ;
//写数据
void Send(LPCLIENTCONTEXT lpContext, CString strData);
private:
//根据消息overlapped的类型,处理消息
BOOL ProcessIOMessage(IOType opCode, LPCLIENTCONTEXT lpContext , DWORD dwIoSize);
//通知客户连接时初始化成功
BOOL OnClientInitializing(LPCLIENTCONTEXT lpContext, DWORD dwIoSize);
//通知读客户数据成功
BOOL OnClientReading(LPCLIENTCONTEXT lpContext, DWORD dwIoSize);
//通知用户写数据成功
BOOL OnClientWriting(LPCLIENTCONTEXT lpContext, DWORD dwIoSize);
//通知用户退出或连接中断
void FreeClientContext(LPCLIENTCONTEXT lpContext);
//在端口上产生线程
void CreateWorkerThread();
//关闭完成端口
void CloseCompletionPort();
//分配连接overlappedplus
LPOVERLAPPEDPLUS AllocateOverlappedPlus(IOType ioType);
//分配连接进入的客户的相关信息
LPCLIENTCONTEXT AllocateContext();
//释放overlappedplus
void FreeOverlappedPlus(LPOVERLAPPEDPLUS lpOlp);
private:
//结束端口完成
HANDLE m_hKillEvent;
//完成端口句柄
HANDLE m_hIocp;
//线程数
DWORDm_dwThreads;
//产生监听socket
SOCKET m_sListen;
};
#endif // !defined(AFX_IOCPSERVER_H__1EC64F02_5939_46BF_B121_DEDD88DB2D1B__INCLUDED_)
显示评论签名
取消批量删除批量删除