bool CSocketRecvTask::ProcessRecvEnts(epoll_event event) { int connfd = 0; sockaddr_in v_ClntAddr; socklen_t addrlen = sizeof(sockaddr_in); epoll_event ev; if(event.data.fd == m_Epoll.GetListenSocket()) { connfd = accept(m_Epoll.GetListenSocket(), (struct sockaddr *)&v_ClntAddr,&addrlen); if (connfd < 0) { LogError("accept error"); } LogInf("recv a new client"); fcntl(connfd, F_SETFL, fcntl(connfd, F_GETFD, 0)|O_NONBLOCK); ev.events = EPOLLIN | EPOLLOUT | EPOLLET; ev.data.fd = connfd; if(epoll_ctl(m_Epoll.m_iEpollfd, EPOLL_CTL_ADD, connfd, &ev) < 0) { LogError("Add connfd error"); close(connfd); } else { SocketInformation* pNewSocket = new SocketInformation(); pNewSocket->sockId = connfd; pthread_mutex_init(&(pNewSocket->OutputChainLock), NULL); pthread_mutex_lock(&m_Epoll.m_SocketInfoLock); m_Epoll.m_SocketInfo.insert(pair<int, SocketInformation*>(connfd, pNewSocket)); pthread_mutex_unlock(&m_Epoll.m_SocketInfoLock); m_Epoll.RecvDataProc->AddClient(connfd); } } else if(event.events&EPOLLIN)//to recv data { //printf("----------------EPOLLIN---------------------\n"); ProcessRecvData(event); } else if(event.events&EPOLLOUT) { //LogInf("-------------------EPOLLOUT-------------"); map<int, SocketInformation*>::iterator it; pthread_mutex_lock(&m_Epoll.m_SocketInfoLock); it = m_Epoll.m_SocketInfo.find(event.data.fd); if(it == m_Epoll.m_SocketInfo.end()) { pthread_mutex_unlock(&m_Epoll.m_SocketInfoLock); return false; } it->second->CurrSendState = SEND_STATE_ALLOW; pthread_mutex_unlock(&m_Epoll.m_SocketInfoLock); //add to list to trigger to send data pthread_mutex_lock(&m_Epoll.m_SendingListLock); CSocketSendTask* pTask = new CSocketSendTask(m_Epoll, event.data.fd); m_Epoll.SendThreadManager.AddTask(event.data.fd,pTask); pthread_mutex_unlock(&m_Epoll.m_SendingListLock); pthread_cond_signal(&m_Epoll.m_SendingListReady); //LogInf("-------------------EPOLLOUT end-------------"); } else { LogInf("socket %d quit1", event.data.fd); epoll_ctl(m_Epoll.m_iEpollfd, EPOLL_CTL_DEL, event.data.fd, &ev); close(event.data.fd); m_Epoll.RecvDataProc->QuitClient(event.data.fd); } return true; }
//recv & send messages void* MessageHandlerThread(int *sockfd) { char recvBuf[MAX_BUF + 1]; char sendBuf[MAX_BUF + 1]; int newfd, ret; int totalSend = strlen(sendBuf); char *pSend = sendBuf; newfd = *sockfd; bzero(recvBuf, MAX_BUF + 1); bzero(sendBuf, MAX_BUF + 1); int loop = 1; while(loop) { ret = recv(newfd, recvBuf, sizeof(recvBuf), 0); if(ret < 0) { if(errno == EAGAIN) break; else { EpollDel(epfd, newfd); return NULL; } } else if(ret == 0) { perror("connection closed\n"); EpollDel(epfd, newfd); return NULL; } else { if(ret == sizeof(recvBuf)) loop = 1; else loop = 0; } } // fflush(stdout); //parse recvdata & handle printf("recvBuf : %s\n", recvBuf); if(ProcessRecvData(conn, recvBuf, sendBuf, newfd) < 0) { perror("process error\n"); return NULL; } printf("sendBuf : %s\n", sendBuf); //in common it is writable /* while(1) { ret = send(newfd, pSend, totalSend, 0); if(ret < 0) { if(errno == EINTR) return NULL; if(errno == EAGAIN) { usleep(1000); continue; } return NULL; } if(ret == totalSend) return NULL; totalSend -= ret; pSend += ret; } */ ret = send(newfd, sendBuf, sizeof(sendBuf), 0); if(ret < 0) { perror("send error\n"); } EpollDel(epfd, newfd); close(newfd); return NULL; }
BOOL KApexProxy::Breathe() { BOOL bResult = false; int nRetCode = false; IKG_Buffer* piBuffer = NULL; BOOL bConnectionAlive = true; BYTE* pbyRecvData = NULL; size_t uRecvDataLen = 0; // if (m_piSocketStream == NULL) // Try Connect // { // nRetCode = Connect( // g_pSO3GameCenter->m_Settings.m_szApexServerIP, // g_pSO3GameCenter->m_Settings.m_nApexServerPort // ); // KG_PROCESS_ERROR(nRetCode); // } KG_PROCESS_ERROR(m_piSocketStream); // assert(m_piSocketStream); if (m_bSendErrorFlag) { bConnectionAlive = false; m_bSendErrorFlag = false; goto Exit0; } while (true) { timeval TimeVal = {0, 0}; if (g_pSO3GameCenter->m_nTimeNow - m_nLastPingTime > g_pSO3GameCenter->m_Settings.m_nApexPingCycle) { DoPingSignal(); m_nLastPingTime = g_pSO3GameCenter->m_nTimeNow; } nRetCode = m_piSocketStream->CheckCanRecv(&TimeVal); if (nRetCode == -1) { bConnectionAlive = false; goto Exit0; } if (nRetCode == 0) { break; } KGLOG_PROCESS_ERROR(nRetCode == 1); KG_COM_RELEASE(piBuffer); nRetCode = m_piSocketStream->Recv(&piBuffer); if (nRetCode == -1) { bConnectionAlive = false; goto Exit0; } KGLOG_PROCESS_ERROR(nRetCode == 1); pbyRecvData = (BYTE*)piBuffer->GetData(); KGLOG_PROCESS_ERROR(pbyRecvData); uRecvDataLen = piBuffer->GetSize(); ProcessRecvData(pbyRecvData, uRecvDataLen); } ClearTimeoutKickNode(); bResult = true; Exit0: if (m_piSocketStream && !bConnectionAlive) { KGLogPrintf(KGLOG_INFO, "[ApexProxy] Connection lost."); KG_COM_RELEASE(m_piSocketStream); } KG_COM_RELEASE(piBuffer); return bResult; }