void CNetChannel::SetSocketChn(ISocketChannel* pChn,INT32 iChnStatus) { if( m_pSocketChn ) { if( pChn ) { LOG2_DEBUG( "ChnType(%d) Exist Socket: %s:%d => %s:%d.\n", GetChnType(), GetLocalIPAddrString(),GetLocalPort(), GetRemoteIPAddrString(),GetRemotePort()); CMM_ASSERT(0); } m_MutexSend.Lock(); ISocketChannel *pSocket = m_pSocketChn; m_pSocketChn = NULL; m_MutexSend.Unlock(); if( pSocket ) { pSocket->CloseChannelEx(); } } CGSAutoMutex locker( &m_MutexSend); m_bSendPulse = 0; m_pSocketChn = pChn; m_iNetChnStatus = iChnStatus; m_bSendDisconnectEvent = 0; }
INT32 CNetChannel::CloseChannelEx() { if(m_pSocketChn) { LOG2_DEBUG( "ChnType(%d) Close Socket: %s:%d => %s:%d .\n", GetChnType(), GetLocalIPAddrString(),GetLocalPort(), GetRemoteIPAddrString(),GetRemotePort()); m_MutexSend.Lock(); ISocketChannel *pSocket = m_pSocketChn; m_pSocketChn = NULL; m_MutexSend.Unlock(); if( pSocket ) { pSocket->CloseChannel(); } } CGSAutoMutex locker( &m_MutexSend); m_iSendPulseCount = 0; m_iReConnectCount = 0; m_iNetRecvDataCount = 0; m_iCurRecvPos = 0; m_iNetChnStatus = NET_CHANNEL_STATUS_INVALID; m_bSendPulse = 0; m_bSendDisconnectEvent = 0; return 0; }
void CNetChannel::SendPulse() { if( m_bSendPulse && m_iNetChnStatus == NET_CHANNEL_STATUS_ACTIVE ) { m_bSendPulse = 0; LOG2_DEBUG( "ChnType(%d) %s:%d => %s:%d. Send Pulse packet On: %ld.\n", GetChnType(), GetLocalIPAddrString(),GetLocalPort(), GetRemoteIPAddrString(),GetRemotePort(), (long)time(NULL) ); m_MutexSend.Lock(); SendRemoteData(NULL, 0); m_MutexSend.Unlock(); } }
INT32 CNetChannel::ReleaseNetChannel() { if(m_pSocketChn) { LOG2_DEBUG( "ChnType(%d) Close Socket: %s:%d => %s:%d .\n", GetChnType(), GetLocalIPAddrString(),GetLocalPort(), GetRemoteIPAddrString(),GetRemotePort()); m_pSocketChn->CloseChannelEx(); m_pSocketChn = NULL; } if(m_pRecvBuf) { free(m_pRecvBuf); m_pRecvBuf = NULL; } if(m_pRecvPackBuf) { free(m_pRecvPackBuf); m_pRecvPackBuf = NULL; } if(m_pExtRecvPackBuf) { free(m_pExtRecvPackBuf); m_pExtRecvPackBuf = NULL; } if(m_pSendPackBuf) { free(m_pSendPackBuf); m_pSendPackBuf = NULL; } if(m_pExtSendPackBuf) { free(m_pExtSendPackBuf); m_pExtSendPackBuf = NULL; } m_bSendDisconnectEvent = 0; return 0; }
/* ------------------------------------------------------------------------- */ static int OnMessageReceived(TServant *const servant, ezxml_t message) { int ret = -EXIT_SUCCESS; #ifdef UNIT_TESTS if (g_Servant_OnMessageReceived) g_Servant_OnMessageReceived(servant, message); #endif assert(message); do { const char *req; const char *error; error = ezxml_error(message); if ('\0' != error[0]) { LOG2_ERROR("servant", "the session (%u) received an invalid " "formated xml message: %s", servant->m_session.m_id, error); ret = -EXIT_FAILURE; break; } req = ezxml_name(message); LOG2_DEBUG("servant", "the session (%u) received '%s' request", servant->m_session.m_id, req); if (strcmp(req, "update") == 0) { if (servant->m_reg) { if ((ret = Reg_Update(servant->m_reg, message))) LOG2_ERROR("servant", "the session (%u) failed to update " "the registry", servant->m_session.m_id, req); } } else if (strcmp(req, "retrieve") == 0) { if (servant->m_reg) { ezxml_t status = ezxml_new("status"); ret = Reg_Get(servant->m_reg, message, status); TxMessage(servant, status); ezxml_free(status); LOG2_DEBUG("servant", "the session (%u) replied to '%s' request", servant->m_session.m_id, req); } } else { LOG2_WARNING("servant", "the session (%u) received an undefined " "request (%s)", servant->m_session.m_id, req); ret = -EXIT_FAILURE; } } while(0); ezxml_free(message); return ret; }
INT32 CNetChannel::OnCheckStatus() { INT32 iNetDataTimeout; INT32 iRet; fnNetEvent OnNetEventCB; if(NET_CHANNEL_STATUS_INVALID == m_iNetChnStatus) { return 0; } SendPulse(); //长期收不到网络包 m_iNetRecvDataCount++; iNetDataTimeout = GetNetDataTimeout(); if(m_iNetChnStatus != NET_CHANNEL_STATUS_ACTIVE) { LOG2_DEBUG( "ChnType(%d) %s:%d => %s:%d. Set timeout.\n", GetChnType(), GetLocalIPAddrString(),GetLocalPort(), GetRemoteIPAddrString(),GetRemotePort()); m_iNetRecvDataCount = iNetDataTimeout + 1; } if( m_iNetRecvDataCount == iNetDataTimeout || (m_bSendDisconnectEvent && m_iNetChnStatus != NET_CHANNEL_STATUS_ACTIVE) ) { LOG2_DEBUG( "ChnType(%d) %s:%d => %s:%d. Keeplavie timeout %d>=%d. IsDisCnn:%d\n", GetChnType(), GetLocalIPAddrString(),GetLocalPort(), GetRemoteIPAddrString(),GetRemotePort(), m_iNetRecvDataCount,iNetDataTimeout, m_bSendDisconnectEvent ); m_iNetRecvDataCount = 0; m_bSendDisconnectEvent = 0; OnNetEventCB = GetNetEventEntry(); if(NULL != OnNetEventCB) { SetChnStatus(NET_CHANNEL_STATUS_SHUTDOWN); OnNetEventCB(GetNetEventCaller(), this, NET_EVENT_CLOSE, NULL); } return 0; } if( m_iNetRecvDataCount > iNetDataTimeout) { m_iNetRecvDataCount = iNetDataTimeout; } if(NET_CHANNEL_TYPE_CLIENT == GetChnType()) { INT32 iPulseTime = GetNetPulseTime(); //客户端需要主动发送心跳包,掉线需要重连 if( m_iNetChnStatus == NET_CHANNEL_STATUS_ACTIVE ) { m_iSendPulseCount++; } if( m_iSendPulseCount * 1250 >= iPulseTime ) { //发送心跳 // m_MutexSend.Lock(); // SendRemoteData(NULL, 0); // m_MutexSend.Unlock(); m_bSendPulse = 1; m_iSendPulseCount = 0; } //重连操作 INT32 iReConnect = GetSupportReConnect(); INT32 iNetStat = GetChnStatus(); if( !m_bSendDisconnectEvent && (NET_CHANNEL_STATUS_NO_CONNECT == iNetStat || NET_CHANNEL_STATUS_SOCKET_ERROR == iNetStat || NET_CHANNEL_STATUS_SHUTDOWN == iNetStat) ) { if(SUPPORT_RECONNECT == iReConnect) { m_iReConnectCount++; if(m_iReConnectCount * 1000 >= GetReConnectTime()) { LOG2_ERROR( "ChnType(%d) %s:%d => %s:%d. Reconnect status:%d On: %ld.\n", GetChnType(), GetLocalIPAddrString(),GetLocalPort(), GetRemoteIPAddrString(),GetRemotePort(), iNetStat, (long)time(NULL) ); m_iReConnectCount = 0; INT32 iReuse = GetReuseNetPortFlag(); if (iReuse == REUSE_NETPORT_FLAG) { iRet = ConnectServer(GetRemoteIPAddrString(), GetRemotePort(), GetLocalIPAddrString(), GetLocalPort()); } else { iRet = ConnectServer(GetRemoteIPAddrString(), GetRemotePort(), "", 0); } if(0 == iRet) { LOG2_ERROR( "Connect %s:%d bind: %s:%d fail.\n", GetRemoteIPAddrString(), GetRemotePort(), GetLocalIPAddrString(), GetLocalPort() ); m_iNetRecvDataCount = 0; OnNetEventCB = GetNetEventEntry(); if(NULL != OnNetEventCB) { OnNetEventCB(GetNetEventCaller(), this, NET_EVENT_CONNECT, NULL); } } } } } } return 0; }
INT32 CNetChannel::OnDataArrive(void* pData, INT32 iDataLen) { INT32 iRet; char* pMSG = NULL; INT32 iMSGLen; INT32 iPayloadLen; char* pCopyData; INT32 iHeadPos; INT32 iFlag = 0; char* pHead; INT32 iResLen; m_Mutex.Lock(); memcpy(m_pRecvBuf + m_iCurRecvPos, pData, iDataLen); m_iCurRecvPos += iDataLen; pHead = m_pRecvBuf; iResLen = m_iCurRecvPos; while(TRUE) { iRet = DePackData(pHead, iResLen, (void**)&pMSG, &iMSGLen, (void**)&pCopyData); switch(iRet) { case 0://成功收到包 m_iNetRecvDataCount = 0; iPayloadLen = iMSGLen - sizeof(StruCommuHeader); if(0 == iPayloadLen)//心跳包 { LOG2_DEBUG( "ChnType(%d) %s:%d => %s:%d. Rcv Pulse packet On:%ld.\n", GetChnType(), GetLocalIPAddrString(),GetLocalPort(), GetRemoteIPAddrString(),GetRemotePort(), (long) time(NULL)); OnRecvPulse(); } else { StruCommuPacket* pCommuPacket; pCommuPacket = (StruCommuPacket*)pCopyData; RecvPacketSlice(pCommuPacket); } iHeadPos = pMSG - pHead; if(iHeadPos + iMSGLen < iResLen) { pHead = pHead + iHeadPos + iMSGLen; iResLen = iResLen - iHeadPos - iMSGLen; iFlag = 1; } else { m_iCurRecvPos = 0; iFlag = 0; } break; case 1://包没有收完 case 3: case -1: iFlag = 0; if(pHead != m_pRecvBuf) { memcpy(m_pRecvBuf, pHead, iResLen); m_iCurRecvPos = iResLen; } break; case 2://无包头 if(iResLen >= 4) { memcpy(m_pRecvBuf, pHead + iResLen -3, 3); m_iCurRecvPos = 3; //剩余3字节有可能是头的一部分 } else { //never happend CMM_ASSERT(0); m_iCurRecvPos = 0; } iFlag = 0; break; default: iFlag = 0; break; } if(!iFlag) { break; } } m_Mutex.Unlock(); return 0; }
INT32 CNetChannel::RecvPacketSlice(StruCommuPacket* pCommuPacket) { fnNetEvent pNetEventFn; void* pNetEventCaller; CBufferObj* pFreeBuf; INT32 iDone = 0; INT32 iTotalLen = 0; CNetMessage UserMsg; INT32 iRet; if(NULL == pCommuPacket) { CMM_ASSERT(0); return -1; } if(pCommuPacket->Header.iSessionID != m_PrePacketHeader.iSessionID)//切换Session { if(0 == m_PrePacketHeader.iSessionID) //第一个包 { } else //Session 丢包了 { LOG2_DEBUG( "ChnType(%d) %s:%d => %s:%d. Lost packet.\n", GetChnType(), GetLocalIPAddrString(),GetLocalPort(), GetRemoteIPAddrString(),GetRemotePort()); //清空 m_MgrRecvBuffer.ClearBuffer(); //暂时不做重传处理 } if(pCommuPacket->Header.iTotalPacket > 1) { memcpy(&m_PrePacketHeader, &pCommuPacket->Header, sizeof(StruCommuHeader)); } else//只有1个包 { iDone = 1; } pFreeBuf = m_pBufferArray->GetFreeBuffer(); if(NULL == pFreeBuf) { return -2; } pFreeBuf->SetData(this, pCommuPacket->Payload, pCommuPacket->Header.iLength); m_MgrRecvBuffer.PushBuffer(pFreeBuf); } else { pFreeBuf = m_pBufferArray->GetFreeBuffer(); if(NULL == pFreeBuf) { LOG2_FATAL( "GetFreeBuffer fail.\n"); return -2; } pFreeBuf->SetData(this, pCommuPacket->Payload, pCommuPacket->Header.iLength); m_MgrRecvBuffer.PushBuffer(pFreeBuf); if(pCommuPacket->Header.iTotalPacket == pCommuPacket->Header.iCurPacket) { iDone = 1; memset(&m_PrePacketHeader, 0, sizeof(m_PrePacketHeader)); } } if(iDone) { if(NULL == m_pRecvPackBuf || m_iRecvPackBufSize <= 0) { return -1; } iTotalLen = m_MgrRecvBuffer.GetDataLen(); if(iTotalLen > m_iRecvPackBufSize) { m_pExtRecvPackBuf = (char*)malloc(iTotalLen); if(NULL == m_pExtRecvPackBuf) { LOG2_FATAL( "malloc %d fail.\n", iTotalLen); return -2; } } else { m_pExtRecvPackBuf = m_pRecvPackBuf; } m_MgrRecvBuffer.GetData(m_pExtRecvPackBuf); m_MgrRecvBuffer.ClearBuffer(); iRet = DePacketUserMsg(m_pExtRecvPackBuf, &UserMsg); if(UserMsg.GetMSGLen() > iTotalLen) { char* pTempMsg = (char*)malloc(UserMsg.GetMSGLen()); if(NULL == pTempMsg) { LOG2_FATAL( "malloc %d fail.\n", UserMsg.GetMSGLen()); return -2; } memcpy(pTempMsg, m_pExtRecvPackBuf, iTotalLen); free(m_pExtRecvPackBuf); m_pExtRecvPackBuf = pTempMsg; iRet = DePacketUserMsg(m_pExtRecvPackBuf, &UserMsg); } pNetEventFn = GetNetEventEntry(); pNetEventCaller = GetNetEventCaller(); if(pNetEventFn) { pNetEventFn(pNetEventCaller, this, NET_EVENT_READ, &UserMsg); } if(iTotalLen > m_iRecvPackBufSize) { free(m_pExtRecvPackBuf); } m_pExtRecvPackBuf = NULL; } return 0; }
INT32 CNetChannel::ConnectServer(char* pszRemoteIPAddr, UINT16 uiRemotePort, char* pszBindingIPAddr, UINT16 uiBindingPort) { INT32 iRet; enumNetProtocolType euPType; LOG2_INFO("ChnType(%d) Connect %s:%d bind:%s:%d", GetChnType(), pszRemoteIPAddr, uiRemotePort, pszBindingIPAddr ? pszBindingIPAddr : "0" , uiRemotePort ); if(m_pSocketChn) { LOG2_DEBUG("ChnType(%d) Close Socket: %s:%d => %s:%d .\n", GetChnType(), GetLocalIPAddrString(),GetLocalPort(), GetRemoteIPAddrString(),GetRemotePort()); m_MutexSend.Lock(); ISocketChannel *pSocket = m_pSocketChn; m_pSocketChn = NULL; m_MutexSend.Unlock(); if( pSocket ) { pSocket->CloseChannelEx(); } } if(NULL == m_pSocketChn) { if(m_pNetService) { if(GetProtocolType() == PROTOCOL_TYPE_TCP) { euPType = NET_PROTOCOL_TCP; } else { euPType = NET_PROTOCOL_UDP; } ISocketChannel *pSocket = NULL; iRet = m_pNetService->AddClientChannel(m_szRemoteIPAddr, uiRemotePort, pszBindingIPAddr, uiBindingPort, euPType, &pSocket); if(iRet < 0 || NULL == pSocket) { LOG2_ERROR("ChnType(%d) Connect %s:%d bind:%s:%d protype:%d fail.", GetChnType(), pszRemoteIPAddr, uiRemotePort, pszBindingIPAddr ? pszBindingIPAddr : "0" , uiRemotePort,(int) euPType ); return -1; } SetSocketChn( pSocket, NET_CHANNEL_STATUS_ACTIVE ); LOG2_DEBUG("ChnType(%d) Connect Socket: %s:%d => %s:%d OK.\n", GetChnType(), GetLocalIPAddrString(),GetLocalPort(), GetRemoteIPAddrString(),GetRemotePort()); } else { CMM_ASSERT(0); return -1; } } else { iRet = m_pSocketChn->ReConnect(); } return iRet; }