int32 onPacketAppend(int32 addsize, bool inseparable = true) { if(pCurrPacket_ == NULL) { newPacket(); } int32 packetmaxsize = PACKET_MAX_CHUNK_SIZE(); int32 totalsize = (int32)pCurrPacket_->totalSize(); int32 fwpos = (int32)pCurrPacket_->wpos(); if(inseparable) fwpos += addsize; if(fwpos >= packetmaxsize) { TRACE_BUNDLE_DATA(false, pCurrPacket_, pCurrMsgHandler_, totalsize); packets_.push_back(pCurrPacket_); currMsgPacketCount_++; newPacket(); totalsize = 0; } int32 remainsize = packetmaxsize - totalsize; int32 taddsize = addsize; // 如果 当前包剩余空间小于要添加的字节则本次填满此包 if(remainsize < addsize) taddsize = remainsize; currMsgLength_ += taddsize; return taddsize; }
//------------------------------------------------------------------------------------- void Bundle::finish(bool issend) { KBE_ASSERT(pCurrPacket_ != NULL); if(issend) { currMsgPacketCount_++; packets_.push_back(pCurrPacket_); } // 此处对于非固定长度的消息来说需要设置它的最终长度信息 if(currMsgHandlerLength_ < 0 || g_packetAlwaysContainLength) { Packet* pPacket = pCurrPacket_; if(currMsgPacketCount_ > 0) pPacket = packets_[packets_.size() - currMsgPacketCount_]; currMsgLength_ -= MERCURY_MESSAGE_ID_SIZE; currMsgLength_ -= MERCURY_MESSAGE_LENGTH_SIZE; memcpy(&pPacket->data()[currMsgLengthPos_], (uint8*)&currMsgLength_, MERCURY_MESSAGE_LENGTH_SIZE); } if(issend) { currMsgHandlerLength_ = 0; TRACE_BUNDLE_DATA(false, pCurrPacket_, pCurrMsgHandler_, this->totalSize()); pCurrPacket_ = NULL; } currMsgID_ = 0; currMsgPacketCount_ = 0; currMsgLength_ = 0; currMsgLengthPos_ = 0; }
//------------------------------------------------------------------------------------- void Channel::handleMessage(KBEngine::Mercury::MessageHandlers* pMsgHandlers) { if (this->isDestroyed()) { ERROR_MSG("Channel::handleMessage(%s): channel[%p] is destroyed.\n", this->c_str(), this); return; } if(this->isCondemn()) { ERROR_MSG("Channel::handleMessage(%s): channel[%p] is condemn.\n", this->c_str(), this); //this->destroy(); return; } try { BufferedReceives::iterator packetIter = bufferedReceives_.begin(); for(; packetIter != bufferedReceives_.end(); packetIter++) { Packet* pPacket = (*packetIter); while(pPacket->totalSize() > 0) { if(fragmentDatasFlag_ == FRAGMENT_DATA_UNKNOW) { if(currMsgID_ == 0) { if(MERCURY_MESSAGE_ID_SIZE > 1 && pPacket->opsize() < MERCURY_MESSAGE_ID_SIZE) { writeFragmentMessage(FRAGMENT_DATA_MESSAGE_ID, pPacket, MERCURY_MESSAGE_ID_SIZE); break; } (*pPacket) >> currMsgID_; pPacket->messageID(currMsgID_); } Mercury::MessageHandler* pMsgHandler = pMsgHandlers->find(currMsgID_); if(pMsgHandler == NULL) { TRACE_BUNDLE_DATA(true, pPacket, pMsgHandler, pPacket->totalSize()); WARNING_MSG("Channel::handleMessage: invalide msgID=%d, msglen=%d, from %s.\n", currMsgID_, pPacket->totalSize(), c_str()); currMsgID_ = 0; currMsgLen_ = 0; condemn(); break; } TRACE_BUNDLE_DATA(true, pPacket, pMsgHandler, pPacket->totalSize()); // 如果没有可操作的数据了则退出等待下一个包处理。 //if(pPacket->opsize() == 0) // 可能是一个无参数数据包 // break; if(currMsgLen_ == 0) { if(pMsgHandler->msgLen == MERCURY_VARIABLE_MESSAGE || g_packetAlwaysContainLength) { // 如果长度信息不完整, 则等待下一个包处理 if(pPacket->opsize() < MERCURY_MESSAGE_LENGTH_SIZE) { writeFragmentMessage(FRAGMENT_DATA_MESSAGE_LENGTH, pPacket, MERCURY_MESSAGE_LENGTH_SIZE); break; } else (*pPacket) >> currMsgLen_; } else currMsgLen_ = pMsgHandler->msgLen; } if(currMsgLen_ > MERCURY_MESSAGE_MAX_SIZE / 2) { WARNING_MSG("Channel::handleMessage(%s): msglen is error! msgID=%d, msglen=(%d:%d), from %s.\n", pMsgHandler->name.c_str(), currMsgID_, currMsgLen_, pPacket->totalSize(), c_str()); currMsgLen_ = 0; condemn(); break; } if(pFragmentStream_ != NULL) { pMsgHandler->handle(this, *pFragmentStream_); MemoryStream::ObjPool().reclaimObject(pFragmentStream_); pFragmentStream_ = NULL; } else { if(pPacket->opsize() < currMsgLen_) { writeFragmentMessage(FRAGMENT_DATA_MESSAGE_BODY, pPacket, currMsgLen_); break; } // 临时设置有效读取位, 防止接口中溢出操作 size_t wpos = pPacket->wpos(); // size_t rpos = pPacket->rpos(); size_t frpos = pPacket->rpos() + currMsgLen_; pPacket->wpos(frpos); pMsgHandler->handle(this, *pPacket); // 防止handle中没有将数据导出获取非法操作 if(currMsgLen_ > 0) { if(frpos != pPacket->rpos()) { CRITICAL_MSG("Channel::handleMessage(%s): rpos(%d) invalid, expect=%d. msgID=%d, msglen=%d.\n", pMsgHandler->name.c_str(), pPacket->rpos(), frpos, currMsgID_, currMsgLen_); pPacket->rpos(frpos); } } pPacket->wpos(wpos); } currMsgID_ = 0; currMsgLen_ = 0; } else { mergeFragmentMessage(pPacket); } } if(pPacket->isTCPPacket()) TCPPacket::ObjPool().reclaimObject(static_cast<TCPPacket*>(pPacket)); else UDPPacket::ObjPool().reclaimObject(static_cast<UDPPacket*>(pPacket)); }