????????????????????????????????????????4????????????????????????????????????????????????????????μ????????4?????????????????????????????????????????????????????????????????????????
????IOCP?????????
#pragma once
#include <string>
#include <winsock2.h>
#include <Windows.h>
#include <vector>
#include <iostream>
#include "CThreadPool.h"
#include "WorkA.h"
#include "WorkB.h"
using namespace std;
#pragma comment(lib?? "Ws2_32.lib")      // Socket???????????????
//#pragma comment(lib?? "Kernel32.lib")
#define DefaultIP  "127.0.0.1"
#define DefaultPort 9999
#define DefaultClientNum 6000
#define MessMaxLen   1024
#define DataBuffSize   2 * 1024
/**
* ?????????PER_IO_DATA
* ???幦??????I/O??????????壬??????IO????
**/
typedef struct
{
OVERLAPPED overlapped;
WSABUF databuff;
char buffer[ DataBuffSize ];
int BufferLen;
int operationType;
SOCKET socket;
}PER_IO_OPERATEION_DATA?? *LPPER_IO_OPERATION_DATA?? *LPPER_IO_DATA?? PER_IO_DATA;
/**
* ?????????PER_HANDLE_DATA
* ????洢????????????????????????????????????????????????????????
* ??????????????????????????????????洢???y????У??????????????????á?
**/
typedef struct
{
SOCKET socket;
SOCKADDR_STORAGE ClientAddr;
}PER_HANDLE_DATA?? *LPPER_HANDLE_DATA;
//??????
class CMYIOCPServer
{
public:
~CMYIOCPServer(void);
bool ServerSetUp();
void SetServerIp(const string & sIP=DefaultIP);
void SetPort(const int &iPort=DefaultPort);
void SetMaxClientNum(const int &iMaxNum = DefaultClientNum);
static DWORD WINAPI  ServerWorkThread(LPVOID CompletionPortID);
static void SendMessage(SOCKET &tSOCKET??char MessAge[MessMaxLen]);
static CMYIOCPServer* GetInstance();
private:
//??з???
CMYIOCPServer(void);
bool  LoadWindowsSocket();
bool InitServerSocket();
bool CreateServerSocker();
static void HandleMessage();
//???????
string m_sServerIP;
int m_iLisenPoint;
string m_sError;
int m_iMaxClientNum;
vector< PER_HANDLE_DATA* > m_vclientGroup;//????????????????
static HANDLE m_hMutex;//??????????????
static HANDLE m_completionPort;
SOCKET m_srvSocket;
static CMYIOCPServer *m_pInstance;
static char m_byteMsg[MessMaxLen];
static CWorkQueue m_CWorkQueue;//????
};
#include "StdAfx.h"
#include "MYIOCPServer.h"
HANDLE  CMYIOCPServer::m_completionPort = NULL;
HANDLE CMYIOCPServer:: m_hMutex = NULL;
CMYIOCPServer* CMYIOCPServer::  m_pInstance = NULL;
char CMYIOCPServer::m_byteMsg[MessMaxLen] = {0} ;
CWorkQueue CMYIOCPServer:: m_CWorkQueue;
/**************************
??????????
***************************/
CMYIOCPServer* CMYIOCPServer::GetInstance()
{
if(NULL == m_pInstance)
{
m_pInstance = new CMYIOCPServer();
}
m_CWorkQueue.Create(10);
return m_pInstance;
}
/**************************
????????
**************************/
CMYIOCPServer::CMYIOCPServer(void)
{
m_iLisenPoint = DefaultPort;
}
/**************************
???????????
**************************/
CMYIOCPServer::~CMYIOCPServer(void)
{
m_CWorkQueue.Destroy(5);
}
/**************************
???÷?????IP
**************************/
void CMYIOCPServer::SetServerIp(const string & sIP)
{
m_sServerIP = sIP;
}
/**************************
???÷????????
**************************/
void  CMYIOCPServer::SetPort(const int &iPort)
{
m_iLisenPoint = iPort;
}
/**************************
?????????????????
**************************/
void  CMYIOCPServer::SetMaxClientNum(const int &iMaxNum)
{
m_iMaxClientNum = iMaxNum;
}
/**************************
???????????????????
???????
**************************/
DWORD WINAPI   CMYIOCPServer::ServerWorkThread(LPVOID CompletionPortID)
{
HANDLE CompletionPort = (HANDLE)CompletionPortID;
DWORD BytesTransferred;
LPOVERLAPPED IpOverlapped;
LPPER_HANDLE_DATA PerHandleData = NULL;
LPPER_IO_DATA PerIoData = NULL;
DWORD RecvBytes;
DWORD Flags = 0;
BOOL bRet = false;
while(true){
bRet = GetQueuedCompletionStatus(m_completionPort?? &BytesTransferred?? (PULONG_PTR)&PerHandleData?? (LPOVERLAPPED*)&IpOverlapped?? INFINITE);
if(bRet == 0){
cerr << "GetQueuedCompletionStatus Error: " << GetLastError() << endl;
continue;
//????????????????????????
//return -1;
}
PerIoData = (LPPER_IO_DATA)CONTAINING_RECORD(IpOverlapped?? PER_IO_DATA?? overlapped);
// ????????????????д?????
if(0 == BytesTransferred){
closesocket(PerHandleData->socket);
GlobalFree(PerHandleData);
GlobalFree(PerIoData);
continue;
}
//??????????
memset(m_byteMsg??0??MessMaxLen);
memcpy(m_byteMsg??PerIoData->databuff.buf??MessMaxLen);
//????????SOCKET???
SOCKET sClientSocket = PerHandleData->socket;
printf("message is %s "??m_byteMsg);
HandleMessage();
//SendMessage(sClientSocket??m_byteMsg);
// ????????????y?????I/O????????
ZeroMemory(&(PerIoData->overlapped)?? sizeof(OVERLAPPED)); // ??????
PerIoData->databuff.len = 1024;
PerIoData->databuff.buf = PerIoData->buffer;
PerIoData->operationType = 0;    // read
WSARecv(PerHandleData->socket?? &(PerIoData->databuff)?? 1?? &RecvBytes?? &Flags?? &(PerIoData->overlapped)?? NULL);
}
return  0;
}