18,356
社区成员
发帖
与我相关
我的任务
分享
case IO_TYPE_ACCEPT:
{
if (pPerSockData->m_AccSocket == INVALID_SOCKET)
{
continue;
}
QueueUserWorkItem(ThreadPoolProc, pThis, WT_EXECUTELONGFUNCTION);
//线程池技术来判断请求是否够用,因为来的请求一下可以有好几个请求
SOCKADDR_IN* ClientAddr = NULL;
SOCKADDR_IN* LocalAddr = NULL;
int remoteLen = sizeof(SOCKADDR_IN), localLen = sizeof(SOCKADDR_IN);
pThis->m_lpfnGetAcceptExSockAddrs( pPerSockData->m_szBuf, MAX_BUF_SIZE - ((sizeof(SOCKADDR_IN)+16)*2) ,sizeof(SOCKADDR_IN)+16, sizeof(SOCKADDR_IN)+16, (LPSOCKADDR*)&LocalAddr, &localLen, (LPSOCKADDR*)&ClientAddr, &remoteLen);
//char aIP[16];
//memcpy((void*)&aIP,(void*)inet_ntoa(ClientAddr->sin_addr),sizeof(SOCKADDR_IN));
//memcpy((void*)ClientAddr,(void*)(SOCKADDR_IN*)((PBYTE)pPerSockData->m_szBuf + (MAX_BUF_SIZE - 2*(sizeof(sockaddr_in) + 16)) + 10+sizeof(sockaddr_in) + 10 + 2), sizeof(sockaddr_in));
/*
解析m_szBuf,将值赋给socket对象//m_szBuf中存储的是用户类型和GUID
*/
TYPE type;
memcpy((void*)&type,(void*)pOverLaps->m_szBuf,sizeof(TYPE));
CPerSocketData *pData = pThis->AssignSockToCompletionPort(pPerSockData->m_AccSocket,*ClientAddr,type);
//将Type的信息绑定到单句柄数据中
pThis->PostRecv(pData,sizeof(COMMAND));
//解析完查看Type的值,如果不是控制端上线则通过遍历Socket的所有对象将是控制端的信息发送给控制端
pThis->PostAccept(pPerSockData);//让我们的容器中不断保持有接受请求的
pThis->RemoveIo(pOverLaps);//完成的请求IO列表删除掉,否则会内存不够
delete pOverLaps;
}
break;
CPerSocketData* CServesDlg::AssignSockToCompletionPort(SOCKET tSocket,SOCKADDR_IN tSockAddr,TYPE type)
{
ASSERT(tSocket != INVALID_SOCKET);//宏的断言判断内部条件是否成立,成立才可以通过,否则产生一个debugBreak
CPerSocketData *pSockData = new CPerSocketData();//如果创建对象的话当函数调用结束后会被释放掉,而这里的指针需要存放到链表中
AddToContextList(pSockData); //添加到数组方便释放
pSockData->m_Socket = tSocket;
//char aIP[16];
if(NULL != &tSockAddr)
{
memcpy((void*)&(pSockData->m_Sockaddr),(void*)&tSockAddr,sizeof(SOCKADDR_IN));//m_Sockaddr的信息更新
char IP[16];
memcpy((void*)IP,(void*)inet_ntoa(pSockData->m_Sockaddr.sin_addr),sizeof(sockaddr_in));
int a =1;
}
bool CServesDlg::PostAccept(CPerSocketData *pSockData)
{
DWORD dwBytesRecv = 0;
ASSERT(pSockData != NULL);//判断传入参数的合法性
COverLappedEx *m_pOverLap = new COverLappedEx(IO_TYPE_ACCEPT,MAX_BUF_SIZE);//定义一个重叠结构
AddToIoList(m_pOverLap);//将单IO数据放入列表中
pSockData->m_AccSocket = WSASocket(AF_INET , SOCK_STREAM , IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); //MAX_BUF_SIZE - ((sizeof(SOCKADDR_IN)+16)*2)
BOOL bRet = m_lpfnAcceptEx(pSockData->m_Socket, pSockData->m_AccSocket, m_pOverLap->m_szBuf, MAX_BUF_SIZE - ((sizeof(SOCKADDR_IN)+16)*2), sizeof(sockaddr_in)+16, sizeof(sockaddr_in)+16, &dwBytesRecv, &m_pOverLap->m_OLap);//第三个参数MAX_BUF_SIZE - ((sizeof(SOCKADDR_IN)+16)*2)而不为0,想通过第一次建立连接,接受发送过来的发送GUID以及机器类型,来标识每一台机器
LocalAddr = (SOCKADDR_IN*)(pOverLaps->m_szBuf + (MAX_BUF_SIZE - 2*(sizeof(sockaddr_in) + 16)) + 10);
ClientAddr = (sockaddr_in*)((pOverLaps->m_szBuf + (MAX_BUF_SIZE - 2*(sizeof(sockaddr_in) + 16)) + 10) + sizeof(sockaddr_in) + 10 + 2);
就行了