#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;
}