http://blog.sina.com.cn/s/blog_6af95663010158j2.html
#ifndef PUBLIC_H
#define PUBLIC_H
//测试消息CommandId
const int COMMANDID1_REQ = 0x00000001;
const int COMMANDID1_REP = 0x80000001;
const int COMMANDID2_REQ = 0x00000002;
const int COMMANDID2_REP = 0x80000002;
//消息Body长度
const int MSGBODYLEN = 64;
const int MSGTOTALLEN = 128;
//Message
typedef struct tagCommonHead
{
u_int uMsgTotalLen;
u_int uCommandId;
}CommonHead_S;
typedef struct tagMsgStr
{
CommonHead_S common;
BYTE cArryMsgBody[MSGBODYLEN];
}MsgStr_S;
#endif
//线程池的基类
#pragma once
#include "stdafx.h"
#include
#include //支持CCriticalSection
#include //支持_beginthreadex
#include
#include
using namespace std;
enum Symbol
{
CreateThreadSuccess,
CreateThreadFailed
};
template //利用模板实现任务通用
class ThreadPool
{
public:
ThreadPool()
{
m_CurrentThreadNum = 0;
m_WantedThreadNum = 0;
}
ThreadPool(int nNum)
{
m_CurrentThreadNum = 0;
m_WantedThreadNum = nNum;
}
virtual ~ThreadPool(){} //基类的析构函数virtual形式。
//设置线程数目
void SetThreadNum(int nNum)
{
m_WantedThreadNum = nNum;
}
//获取冲突域
CCriticalSection& GetCriticalSection()
{
return m_CriticalSection;
}
//向队列中添加任务
void AddTask(T* pTask) //任务类型模板T
{
GetCriticalSection().Lock();
m_TaskQueue.push(pTask);
m_Event.SetEvent();
GetCriticalSection().Unlock();
}
//创建线程
int Run()
{
m_bTerminateThread = false;
HANDLE hHandleThread = NULL;
while (m_CurrentThreadNum < m_WantedThreadNum) //线程池中设定固定个数的线程数
{
hHandleThread = (HANDLE)_beginthreadex(NULL,
0,
ThreadPool::LThreadFun,
(LPVOID)this,
0,
&m_ThreadId); //m_ThreadId为线程ID
if (NULL == hHandleThread)
{
return CreateThreadFailed;
}
else
{
m_CurrentThreadNum++;
m_vecThreadHandle.push_back(hHandleThread);
//AfxMessageBox(_T("Create one thread!"));
}
}
return 0;
}
//终止线程
void TerminateAll()
{
m_bTerminateThread = true;
for (vector::size_type ix=0; ix!=m_vecThreadHandle.size(); ++ix)
{
HANDLE hHandle = m_vecThreadHandle[ix];
if (NULL != hHandle)
{
WaitForSingleObject(hHandle, INFINITE);
CloseHandle(hHandle);
hHandle = NULL;
//AfxMessageBox(_T("close one thread!"));
}
}
m_CurrentThreadNum = 0;
m_vecThreadHandle.clear();
}
protected:
virtual void ProcessFun(T* pTask) = 0; //纯虚函数,此处真正处理任务
private:
static unsigned __stdcall LThreadFun(LPVOID Param)
{
ThreadPool* pThis = (ThreadPool*)Param; //派生类对象转为基类
while (!pThis->m_bTerminateThread)
{
T* pTask = NULL;
pThis->GetCriticalSection().Lock();
if (pThis->m_TaskQueue.empty())
{
pThis->GetCriticalSection().Unlock();
if (WAIT_TIMEOUT == WaitForSingleObject((pThis->m_Event).m_hObject, 10))
{
continue;
}
}
else
{
pTask = pThis->m_TaskQueue.front();
pThis->m_TaskQueue.pop();
pThis->GetCriticalSection().Unlock();
pThis->ProcessFun(pTask); //多态调用派生类重写的方法
}
}
return 0;
}
protected:
queue m_TaskQueue;
int m_WantedThreadNum;
int m_CurrentThreadNum;
u_int m_ThreadId;
CCriticalSection m_CriticalSection;
CEvent m_Event;
vector m_vecThreadHandle; //保存线程HANDLE
bool m_bTerminateThread;
};
//3. 处理消息的线程池
//1).h文件
#ifndef PROCTHREADPOOL_H
#define PROCTHREADPOOL_H
#include "ThreadPoolBase.h"
#include "Public.h"
#include
class MsgInfo
{
public:
SOCKET m_sock;
BYTE cArryMsgLen[MSGTOTALLEN];
};
class ProcThreadPool:public ThreadPool
{
public:
ProcThreadPool(){}
~ProcThreadPool(){}
private:
void ProcessFun(MsgInfo* pMsg);
u_int GetMsgLen(BYTE cArryMsg[]);
u_int GetMsgCommandId(BYTE cArryMsg[]);
void DoCommandMsg(u_int uCommand, SOCKET sock);
};
#endif
//.cpp文件
#include "stdafx.h"
#include "ProcThreadPool.h"
u_int ProcThreadPool::GetMsgLen(BYTE cArryMsg[]) //封装的获取消息长度的方法
{
CommonHead_S* pCommon = (CommonHead_S*)cArryMsg;
u_int uMsgLen = ntohl(pCommon->uMsgTotalLen);
return uMsgLen;
}
u_int ProcThreadPool::GetMsgCommandId(BYTE cArryMsg[]) //获取CommandId的方法
{
CommonHead_S* pCommon = (CommonHead_S*)cArryMsg;
u_int uCommandid = ntohl(pCommon->uCommandId);
return uCommandid;
}
void ProcThreadPool::DoCommandMsg(u_int uCommand, SOCKET sock) //根据收到的不同消息,相应处理
{
if (COMMANDID1_REQ == uCommand)
{
MsgStr_S MsgStr;
memset(MsgStr.cArryMsgBody, 0, MSGBODYLEN);
strcpy((char*)MsgStr.cArryMsgBody, "Command1--Response");
MsgStr.common.uCommandId = htonl(COMMANDID1_REP);
MsgStr.common.uMsgTotalLen = htonl(sizeof(MsgStr_S));
if (SOCKET_ERROR == send(sock, (char*)&MsgStr, sizeof(MsgStr_S), 0))
{
return;
}
}
else if (COMMANDID2_REQ == uCommand)
{
MsgStr_S MsgStr;
memset(MsgStr.cArryMsgBody, 0, MSGBODYLEN);
strcpy((char*)MsgStr.cArryMsgBody, "Command2--Response");
MsgStr.common.uCommandId = htonl(COMMANDID2_REP);
MsgStr.common.uMsgTotalLen = htonl(sizeof(MsgStr_S));
if (SOCKET_ERROR == send(sock, (char*)&MsgStr, sizeof(MsgStr_S), 0))
{
return;
}
}
else
{}
return;
}
void ProcThreadPool::ProcessFun(MsgInfo* pMsg)
{
SOCKET sock = pMsg->m_sock;
u_int uCommandId = GetMsgCommandId(pMsg->cArryMsgLen);
u_int uMsgLen = GetMsgLen(pMsg->cArryMsgLen);
//MsgInfo* pMsgTemp = pMsg;
switch (uCommandId)
{
case COMMANDID1_REQ:
//处理COMMANDID1消息
DoCommandMsg(COMMANDID1_REQ, sock);
break;
case COMMANDID2_REQ:
//处理COMMANDID2消息
DoCommandMsg(COMMANDID2_REQ, sock);
break;
default:
break;
}
delete pMsg;
pMsg = NULL;
return;
}
//4.接收线程池
//1).h文件
#ifndef RECVTHREADPOOL_H
#define RECVTHREADPOOL_H
#include "stdafx.h"
#include "ProcThreadPool.h"
const int RECVTHREADNUM = 5; //接收线程个数
const int PROCTHREADNUM = 5; //处理线程个数
const short PORT = 9876;
class RecvThreadPool:public ThreadPool
{
public:
RecvThreadPool()
{
m_bServerRun = false; //关闭监听线程的标志
}
~RecvThreadPool(){}
int CreateListenThread(); //创建一个监听的线程
void StartProcPool(int nNum) //在接收类中吊起处理线程池
{
m_ProThreadPool.SetThreadNum(nNum);
m_ProThreadPool.Run();
}
void TerminateProcAll()
{
m_ProThreadPool.TerminateAll();
}
private:
void ProcessFun(SOCKET* pSock);
u_int GetMsgLen(BYTE cArryMsgLen[]);
int RecvTotalMsg();
static unsigned __stdcall ListenThread(LPVOID Param);
public:
bool m_bServerRun;
private:
ProcThreadPool m_ProThreadPool;
};
#endif
//2).cpp文件
#include "stdafx.h"
#include "RecvThreadPool.h"
//监听线程
unsigned __stdcall RecvThreadPool::ListenThread(LPVOID Param)
{
RecvThreadPool* pThis = (RecvThreadPool*)Param;
pThis->StartProcPool(PROCTHREADNUM); //将处理消息的线程池吊起
pThis->SetThreadNum(RECVTHREADNUM);
pThis->Run();
WSADATA wsaData;
int err;
err = WSAStartup(MAKEWORD(1, 1), &wsaData);
if ( err != 0 )
{
return 1;
}
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup();
return 1;
}
//创建用于监听的套接字
SOCKET ListenSock = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons( PORT );
int nOpt=1;
setsockopt(ListenSock, SOL_SOCKET, SO_REUSEADDR, (char *) &nOpt, sizeof(int));//重用端口
int nRetBind = bind(ListenSock , (SOCKADDR * )&addrSrv, sizeof( SOCKADDR ) );
if ( SOCKET_ERROR == nRetBind )
{
return 1;
}
int nListenRet = listen( ListenSock, SOMAXCONN);
if (SOCKET_ERROR == nListenRet )
{
return 1;
}
SOCKADDR_IN addrClient;
int len = sizeof( SOCKADDR );
fd_set AcceptFdSet;
struct timeval tv = {0, 100};
while (!pThis->m_bServerRun)
{
//判断监听SOCKET是否关闭
if (INVALID_SOCKET == ListenSock || SOCKET_ERROR == ListenSock)
{
break;
}
FD_ZERO(&AcceptFdSet);
FD_SET(ListenSock, &AcceptFdSet);
int nRetSelect = select(0, &AcceptFdSet, NULL, NULL, &tv); //Linux下0应该为ListenSock+1
if (SOCKET_ERROR == nRetSelect)
{
break;
}
if (0 == nRetSelect)//超时
{
continue;
}
//等待客户请求到来
SOCKET sockConn = accept( ListenSock, ( SOCKADDR * )&addrClient, &len );
if (INVALID_SOCKET == sockConn || SOCKET_ERROR == sockConn || NULL == sockConn)
{
continue;
}
SOCKET* pSock = new SOCKET;
*pSock = sockConn;
pThis->AddTask(pSock);
}
AfxMessageBox(_T("Listen thread exit"));
WSACleanup();
return 0;
}
//创建线程进行监听
int RecvThreadPool::CreateListenThread()
{
if (NULL == _beginthreadex(NULL,
0,
RecvThreadPool::ListenThread,
(LPVOID)this,
0,
NULL))
{
return CreateThreadFailed;
}
return CreateThreadSuccess;
}
//返回消息总长度
u_int RecvThreadPool::GetMsgLen(BYTE cArryMsgLen[])
{
CommonHead_S* pCommon = (CommonHead_S*)cArryMsgLen;
u_int uMsgLen = ntohl(pCommon->uMsgTotalLen);
return uMsgLen;
}
//接收线程池实际处理函数
void RecvThreadPool::ProcessFun(SOCKET* pSock)
{
BYTE* pMsgTotal = new BYTE[MSGTOTALLEN];
memset(pMsgTotal, 0, MSGTOTALLEN);
BYTE* pMsgTotalTemp = pMsgTotal;
//先接收消息头
int nRecvHeadLen = 0;
int nRecvHeadTotalLen = 0;
while (1)
{
nRecvHeadLen = recv(*pSock, (char*)(pMsgTotal + nRecvHeadTotalLen), sizeof(CommonHead_S) - nRecvHeadTotalLen, 0);
if (SOCKET_ERROR == nRecvHeadLen || 0 == nRecvHeadLen) //0表示对方断开了
{
return;
}
nRecvHeadTotalLen += nRecvHeadLen;
if (nRecvHeadTotalLen < sizeof(CommonHead_S))
{
Sleep(200);
continue;
}
if (nRecvHeadTotalLen >= sizeof(CommonHead_S))
{
break;
}
}
u_int uMsgTotal = GetMsgLen(pMsgTotal);
if (uMsgTotal > nRecvHeadTotalLen) //消息总长度>消息头长度,继续接收消息体
{
int nRecvBodyLen = 0;
int nRecvBodyTotalLen = 0;
int nLeftBodyLen = (uMsgTotal - nRecvHeadTotalLen);
while (1)
{
nRecvBodyLen = recv(*pSock, (char*)(pMsgTotal+nRecvHeadTotalLen+nRecvBodyTotalLen),nLeftBodyLen - nRecvBodyTotalLen, 0);
if (SOCKET_ERROR == nRecvBodyLen || 0 == nRecvBodyLen)
{
return;
}
nRecvBodyTotalLen += nRecvBodyLen;
if (nRecvBodyTotalLen < nLeftBodyLen)
{
continue;
}
if (nRecvBodyTotalLen >= nLeftBodyLen)
{
break;
}
}
}
MsgInfo* pMsg = new MsgInfo;
pMsg->m_sock = *pSock;
memset(pMsg->cArryMsgLen, 0, MSGTOTALLEN);
memcpy(pMsg->cArryMsgLen, pMsgTotalTemp, MSGTOTALLEN);
m_ProThreadPool.AddTask(pMsg); //处理线程池去处理
delete [] pMsgTotalTemp;
pMsgTotalTemp = NULL;
delete pSock;
pSock = NULL;
return;
}