Example #1
0
	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;
	}
Example #2
0
//-------------------------------------------------------------------------------------
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;
}
Example #3
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));

		}