void CNiThread::SendData(CBuffer& bufDataSnd,const CString& strClientAddr) { if(bufDataSnd.GetDataLen()<=0 || strClientAddr.GetLength()<=0) return; NI_TASK_PARAM_TYPE* pNiTask = new NI_TASK_PARAM_TYPE; if(pNiTask != NULL) { //pNiTask->pSendData = &bufDataSnd; pNiTask->pSendData = new CBuffer(); if(pNiTask->pSendData!=NULL) { //加装数据包头 if(pNiTask->pSendData->Alloc(bufDataSnd.GetDataLen()+PACKAGE_HEAD_LEN)) { //填写数据包头部 DWORD* pPackageEntityLen = (DWORD*)pNiTask->pSendData->GetBufP(); *pPackageEntityLen=bufDataSnd.GetDataLen(); pNiTask->pSendData->SetDataLen(PACKAGE_HEAD_LEN); pNiTask->pSendData->AppendData(bufDataSnd); //memcpy(pNiTask->pSendData,bufDataSnd.GetBufP(),bufDataSnd.GetDataLen()); //pNiTask->pSendData->SetDataLen(bufDataSnd.GetDataLen()+PACKAGE_HEAD_LEN); } } //填写发送地址 pNiTask->strClientAddr = strClientAddr; //提交发送任务 CommitNiTask(NITASK_SEND,pNiTask); } }
void CNiThread::SendFile(CBuffer& bufDataSnd,const CString& strClientAddr) { if(bufDataSnd.GetDataLen()<=0 || strClientAddr.GetLength()<=0) return; NI_TASK_PARAM_TYPE* pNiTask = new NI_TASK_PARAM_TYPE; if(pNiTask != NULL) { //pNiTask->pSendData = &bufDataSnd; pNiTask->pSendData=new CBuffer(bufDataSnd.GetDataLen()); pNiTask->pSendData->SetData(bufDataSnd); //填写发送地址 pNiTask->strClientAddr = strClientAddr; //提交发送任务 CommitNiTask(NITASK_SEND,pNiTask); } }
void CNiThread::OnSocketReceive(CNotifySocket* pSrcSocket,int nErrorCode) { //当进入预关闭流程时,拒绝外部请求 if(m_bPreShutdown) return; ClientSocketInfoType* pClientInfo = FindClientInfoByAddr(pSrcSocket); if(pClientInfo!=NULL) { //获取Socket内部接收缓冲区长度 int nSocketRecvBufLen = 0; int nSocketOptLen = sizeof(nSocketRecvBufLen); pSrcSocket->GetSockOpt(SO_RCVBUF,&nSocketRecvBufLen,&nSocketOptLen); //当资源不足时关闭对应Socket BOOL bCloseSocket = FALSE; while(TRUE) { CBuffer* pBufRecv; pBufRecv=new CBuffer(nSocketRecvBufLen); //pBufRecv->Alloc(nSocketRecvBufLen); if(pBufRecv!=NULL) { int nRecvLen = pSrcSocket->Receive(pBufRecv->GetBufP(),nSocketRecvBufLen); if(nRecvLen>0) { pBufRecv->SetDataLen(nRecvLen); } else { delete pBufRecv; break; } } else { bCloseSocket = TRUE; break; } PROCESS_RECEIVE: //数据入队 pClientInfo->queRecv.Add(pBufRecv); pBufRecv = NULL; //取缓存的数据总长度 DWORD nSumDataLen = 0; for(int i=0;i<pClientInfo->queRecv.GetCount();++i) { nSumDataLen +=pClientInfo->queRecv[i]->GetDataLen(); } if(pClientInfo->nPackageNeedRecv == 0)//在一个数据包接收任务的开始 { //如果数据总长度超过包头长度 if(nSumDataLen>=PACKAGE_HEAD_LEN) { //合成数据 CBuffer* pBufCompose; pBufCompose=new CBuffer(nSumDataLen); //pBufCompose->Alloc(nSumDataLen); if(pBufCompose != NULL) { BYTE* pOffset = pBufCompose->GetBufP(); //合成数据并清理包头缓存 while(pClientInfo->queRecv.GetCount()>0) { memcpy(pOffset,pClientInfo->queRecv[0]->GetBufP(),pClientInfo->queRecv[0]->GetDataLen()); pOffset += pClientInfo->queRecv[0]->GetDataLen(); delete pClientInfo->queRecv[0]; pClientInfo->queRecv.RemoveAt(0); } pBufCompose->SetDataLen(nSumDataLen); //获得数据包有效数据长度 DWORD nPackageHead = *((int*)pBufCompose->GetBufP()); //根据数据长度进行不同的处理 if( nSumDataLen<nPackageHead+PACKAGE_HEAD_LEN)//如果总长度大于或等于头部长度且没超过需接收的长度,则还有多余的数据需要入接收队列 { //设置待接收数据长度 pClientInfo->nPackageNeedRecv = nPackageHead ; //剪除头部数据 pBufCompose->CutHeadData(PACKAGE_HEAD_LEN); if(pBufCompose->GetDataLen()>0) pClientInfo->queRecv.Add(pBufCompose); else//接收数据长度刚好等于包头 delete pBufCompose; } else //if(nSumDataLen>=nPackageHead+PACKAGE_HEAD_LEN)//数据一次接够的 { int nExtraLen = nSumDataLen-nPackageHead-PACKAGE_HEAD_LEN; CBuffer *pNextMissonHead = NULL; //缓存下次任务数据 if(nExtraLen>0) { pNextMissonHead=new CBuffer(nExtraLen); if(pNextMissonHead != NULL) pNextMissonHead->SetData(pBufCompose->GetBufP()+pBufCompose->GetDataLen()-nExtraLen,nExtraLen); } //剪除尾部下次任务数据 pBufCompose->CutTailData(nExtraLen); //剪除头部数据 pBufCompose->CutHeadData(PACKAGE_HEAD_LEN); //提交事务数据 GetSvrApp()->CommitTask(pBufCompose,pClientInfo->strClientAddr); //处理下次任务 pClientInfo->nPackageNeedRecv = 0; if(pNextMissonHead != NULL) { pBufRecv = pNextMissonHead; goto PROCESS_RECEIVE; } } } else//如果没有足够内存,则关闭对应Socket { bCloseSocket = TRUE; break; } } } else//后继接收任务 { int nExtraLen = nSumDataLen - pClientInfo->nPackageNeedRecv; if(nExtraLen>=0) { //合成数据 CBuffer* pBufCompose; pBufCompose=new CBuffer(nSumDataLen); //pBufCompose->Alloc(nSumDataLen); if(pBufCompose != NULL) { BYTE* pOffeset = pBufCompose->GetBufP(); //合成数据并清理接收缓存队列 while(pClientInfo->queRecv.GetCount()>0) { memcpy(pOffeset,pClientInfo->queRecv[0]->GetBufP(),pClientInfo->queRecv[0]->GetDataLen()); pOffeset += pClientInfo->queRecv[0]->GetDataLen(); delete pClientInfo->queRecv[0]; pClientInfo->queRecv.RemoveAt(0); } pBufCompose->SetDataLen(nSumDataLen); //将超过本次任务长度的部分另外缓存 CBuffer *pNextMissonHead = NULL; if(nExtraLen>0) { pNextMissonHead=new CBuffer(nExtraLen); if(pNextMissonHead != NULL) pNextMissonHead->SetData(pBufCompose->GetBufP()+pClientInfo->nPackageNeedRecv,nExtraLen); } //剪除下次任务数据 pBufCompose->CutTailData(nExtraLen); //提交事务数据 GetSvrApp()->CommitTask(pBufCompose,pClientInfo->strClientAddr); //GetSvrApp()->PostThreadMessageW(UM_COMMIT_TASK,(WPARAM)pBufCompose,(LPARAM)pClientInfo); //处理下次任务 pClientInfo->nPackageNeedRecv = 0; if(pNextMissonHead != NULL) { pBufRecv = pNextMissonHead; goto PROCESS_RECEIVE; } } else//资源不够时,释放资源,关闭相应Socket { bCloseSocket = TRUE; break; } } } } //如果没有足够内存,则关闭对应Socket if(bCloseSocket) { m_mapAddr2ClientInfo.RemoveKey(pSrcSocket->GetPeerAddrStr()); delete pClientInfo; } } }