void LcEpollCli::EpollSend(OverLap* pOverLap) { int fd = pOverLap->fd; pthread_mutex_lock(&m_SndSync); OverLap* pSndList = pOverLap->pSndList; pOverLap->pSndList = NULL; pthread_mutex_unlock(&m_SndSync); while(pSndList) { pSndList->uiSndFinishLen = 0; while(pSndList->uiSndComLen > 0) { int ret = send(fd, pSndList->szpComBuf + pSndList->uiSndFinishLen, pSndList->uiSndComLen, MSG_NOSIGNAL); if(ret == -1 && errno == EAGAIN) { PushRequest(pSndList); return; } else if(ret == 0 || ret > (int)pSndList->uiSndComLen) { RemoveConnect(pOverLap); return; } else if(ret == -1) { RemoveConnect(pOverLap); return; } pSndList->uiSndFinishLen += ret; pSndList->uiSndComLen -= ret; } pOverLap->u64PacketSnd += 1; OverLap* pTmpOverLap = pSndList; pSndList = pSndList->pSndList; pTmpOverLap->pSndList = NULL; m_IONetSndMemQue.Push((long)pTmpOverLap); } }
void LcEpollCli::EpollRecv(OverLap* pOverLap) { int ret = 0; bool bIsHeadChecked = false; while(1) { ret = recv(pOverLap->fd, pOverLap->szpComBuf + pOverLap->uiFinishLen, pOverLap->uiComLen, 0); if(ret == 0 || ret > (int)pOverLap->uiComLen) { m_pCoreLog->Write("error: ret == 0 || ret > %u connect %llu closed", pOverLap->uiComLen, pOverLap->u64SessionID); RemoveConnect(pOverLap); return; } else if(ret == -1 && errno == EAGAIN) { break; } else if(ret == -1) { m_pCoreLog->Write("error: ret < 0, connect %llu closed", pOverLap->u64SessionID); RemoveConnect(pOverLap); return; } pOverLap->uiComLen -= ret; pOverLap->uiFinishLen += ret; switch(CheckPacket(pOverLap, bIsHeadChecked)) { case 0: continue; case 1: case 2: RemoveConnect(pOverLap); return; case 3: case 4: continue; } } }
void CMain_Reactor::ProcessMsg(CMessage * Msg) { switch(Msg->GetType()) { case 0://con exit RemoveConnect(Msg->GetFd()); CMessageAlloctor::FreeMSG(&Msg); break; case 1: // echo { char data[128]; Msg->Readstr(data, sizeof(data)); printf("client data = %s len = %d\n", data, strlen(data)); PushSendQueue(Msg); } break; case 2: { int n1 = Msg->Readint(); int n2 = Msg->Readint(); int sum = n1 + n2; // printf("n1 = %d n2 = %d sum = %d\n", n1, n2, sum); CMessage *ReMsg = CMessageAlloctor::AllocMSG(2); ReMsg->Write(sum); ReMsg->SetFd(Msg->GetFd()); PushSendQueue(ReMsg); CMessageAlloctor::FreeMSG(&Msg); } break; case 3: { bExit_ = true; printf("main exit\n"); CMessageAlloctor::FreeMSG(&Msg); } break; case 100: // new connect { int nLoopid = Msg->Readint(); AddNewConnect(Msg->GetFd(),nLoopid); } break; } }
int LcEpollCli::PushRequest(OverLap* pOverLap) { if(pOverLap == NULL) { return 1; } else if(pOverLap->uiSndComLen == 0) { m_IONetSndMemQue.Push((long)pOverLap); return 1; } OverLap* pConnOverLap; if(m_ConnTable.Search(pOverLap->u64SessionID, pConnOverLap)) { m_pCoreLog->Write("%llu can't be found", pOverLap->u64SessionID); m_IONetSndMemQue.Push((long)pOverLap); return 2; } pthread_mutex_lock(&m_SndSync); OverLap* pTmp = pConnOverLap; while(pTmp->pSndList) { pTmp = pTmp->pSndList; } pTmp->pSndList = pOverLap; pthread_mutex_unlock(&m_SndSync); struct epoll_event ev; ev.events = EPOLLOUT | EPOLLIN | EPOLLET; ev.data.ptr = (void*)pConnOverLap; if(epoll_ctl(m_epSocket, EPOLL_CTL_MOD, pConnOverLap->fd, &ev) == -1) { m_pCoreLog->Write("error: epoll_ctl_mod EPOLLOUT error"); RemoveConnect(pConnOverLap); } return 0; }