上面介紹了怎么樣構(gòu)造消息模板,并用它來靈活地生成各種各樣需要傳送數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu),現(xiàn)在就來分析一下使用模板怎么樣去分析緩沖區(qū)里的數(shù)據(jù),然后獲取消息各個字段數(shù)據(jù),這樣才可以讓別的程序使用起來。
#001?BOOL LLTemplateMessageReader::readMessage(const U8* buffer,
#002?
??????????????????????????????????????????????????????????????????? ??const LLHost&
#003?sender)
#004?{
#005?
???? return decodeData(buffer, sender);
#006?}
?
在LLMessageSystem::checkMessages函數(shù)里調(diào)用readMessage函數(shù)來解包,而函數(shù)readMessage又需要調(diào)用函數(shù)decodeData把緩沖區(qū)buffer里的數(shù)據(jù)分離出來,供其它的程序使用。下面就是函數(shù)decodeData的代碼:
#001?// decode a given message
#002?BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender )
#003?{
#004?
???? llassert( mReceiveSize >= 0 );
#005?
???? llassert( mCurrentRMessageTemplate);
#006?
???? llassert( !mCurrentRMessageData );
#007?
???? delete mCurrentRMessageData; // just to make sure
#008?
?
下面的程序跳過包頭數(shù)據(jù),獲取到真實的數(shù)據(jù)開始位置。
#009?
???? // The offset tells us how may bytes to skip after the end of the
#010?
???? // message name.
#011?
???? U8 offset = buffer[PHL_OFFSET];
#012?
???? S32 decode_pos = LL_PACKET_ID_SIZE + (S32)(mCurrentRMessageTemplate->mFrequency) + offset;
#013?
?
創(chuàng)建一個消息保存當(dāng)前的數(shù)據(jù)字段。
#014?
???? // create base working data set
#015?
???? mCurrentRMessageData = new LLMsgData(mCurrentRMessageTemplate->mName);
#016?
????
?
下面通過消息的模板來獲取緩沖區(qū)里每個字段的數(shù)據(jù)。
#017?
???? // loop through the template building the data structure as we go
#018?
???? LLMessageTemplate::message_block_map_t::const_iterator iter;
#019?
???? for(iter = mCurrentRMessageTemplate->mMemberBlocks.begin();
#020?
??????????? iter != mCurrentRMessageTemplate->mMemberBlocks.end();
#021?
??????????? ++iter)
#022?
???? {
#023?
??????????? LLMessageBlock* mbci = *iter;
#024?
??????????? U8?? repeat_number;
#025?
??????????? S32 i;
#026?
?
先根據(jù)模板查看有多少塊數(shù)據(jù)。
#027?
??????????? // how many of this block?
#028?
?
只有一塊數(shù)據(jù)。
#029?
??????????? if (mbci->mType == MBT_SINGLE)
#030?
??????????? {
#031?
?????????????????? // just one
#032?
?????????????????? repeat_number = 1;
#033?
??????????? }
?
多塊數(shù)據(jù)。
#034?
??????????? else if (mbci->mType == MBT_MULTIPLE)
#035?
??????????? {
#036?
?????????????????? // a known number
#037?
?????????????????? repeat_number = mbci->mNumber;
#038?
??????????? }
?
可變的數(shù)據(jù)塊。
#039?
??????????? else if (mbci->mType == MBT_VARIABLE)
#040?
??????????? {
#041?
?????????????????? // need to read the number from the message
#042?
?????????????????? // repeat number is a single byte
#043?
?????????????????? if (decode_pos >= mReceiveSize)
#044?
?????????????????? {
#045?
????????????????????????? logRanOffEndOfPacket(sender, decode_pos, 1);
#046?
#047?
????????????????????????? // default to 0 repeats
#048?
????????????????????????? repeat_number = 0;
#049?
?????????????????? }
#050?
?????????????????? else
#051?
?????????????????? {
#052?
????????????????????????? repeat_number = buffer[decode_pos];
#053?
????????????????????????? decode_pos++;
#054?
?????????????????? }
#055?
??????????? }
?
沒有定義的數(shù)據(jù)塊。
#056?
???? ?????? else
#057?
??????????? {
#058?
?????????????????? llerrs << "Unknown block type" << llendl;
#059?
?????????????????? return FALSE;
#060?
??????????? }
#061?
#062?
??????????? LLMsgBlkData* cur_data_block = NULL;
#063?
?
?
下面開始循環(huán)分析數(shù)據(jù)塊。
#064?
??????????? // now loop through the block
#065?
??????????? for (i = 0; i < repeat_number; i++)
#066?
??????????? {
?
?
創(chuàng)建數(shù)據(jù)塊結(jié)構(gòu)保存數(shù)據(jù)。
#067?
?????????????????? if (i)
#068?
?????????????????? {
#069?
????????????????????????? // build new name to prevent collisions
#070?
????????????????????????? // TODO: This should really change to a vector
#071?
????????????????????????? cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
#072?
????????????????????????? cur_data_block->mName = mbci->mName + i;
#073?
?????????????????? }
#074?
?????????????????? else
#075?
?????????????????? {
#076?
????????????????????????? cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
#077?
?????????????????? }
#078?
?
添加數(shù)據(jù)塊到當(dāng)前消息結(jié)構(gòu)里。
#079?
?????????????????? // add the block to the message
#080?
?????????????????? mCurrentRMessageData->addBlock(cur_data_block);
#081?
?
開始根據(jù)消息模板的定義去分析緩沖區(qū)里每個字段。
#082?
?????????????????? // now read the variables
#083?
?????????????????? for (LLMessageBlock::message_variable_map_t::const_iterator iter =
#084?
???????????????????????????????? ?mbci->mMemberVariables.begin();
#085?
????????????????????????? ?iter != mbci->mMemberVariables.end(); iter++)
#086?
?????????????????? {
#087?
????????????????????????? const LLMessageVariable& mvci = **iter;
#088?
#089?
????????????????????????? // ok, build out the variables
#090?
????????????????????????? // add variable block
#091?
????????????????????????? cur_data_block->addVariable(mvci.getName(), mvci.getType());
#092?
#093?
????????????????????????? // what type of variable?
#094?
????????????????????????? if (mvci.getType() == MVT_VARIABLE)
#095?
????????????????????????? {
#096?
???????????????????????????????? // variable, get the number of bytes to read from the template
#097?
???????????????????????????????? S32 data_size = mvci.getSize();
#098?
???????????????????????????????? U8 tsizeb = 0;
#099?
???????????????????????????????? U16 tsizeh = 0;
#100?
???????????????????????????????? U32 tsize = 0;
#101?
#102?
???????????????????????????????? if ((decode_pos + data_size) > mReceiveSize)
#103?
???????????????????????????????? {
#104?
??????????????????????????????????????? logRanOffEndOfPacket(sender, decode_pos, data_size);
#105?
#106?
??????????????????????????????????????? // default to 0 length variable blocks
#107?
??????????????????????????????????????? tsize = 0;
#108?
???????????????????????????????? }
#109?
???????????????????????????????? else
#110?
???? ??????????????????????????? {
#111?
??????????????????????????????????????? switch(data_size)
#112?
??????????????????????????????????????? {
#113?
??????????????????????????????????????? case 1:
#114?
?????????????????????????????????????????????? htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U8, 1);
#115?
?????????????????????????????????????????????? tsize = tsizeb;
#116?
?????????????????????????????????????????????? break;
#117?
??????????????????????????????????????? case 2:
#118?
?????????????????????????????????????????????? htonmemcpy(&tsizeh, &buffer[decode_pos], MVT_U16, 2);
#119?
?????????????????????????????????????????????? tsize = tsizeh;
#120?
?????????????????????????????????????????????? break;
#121?
??????????????????????????????????????? case 4:
#122?
?????????????????????????????????????????????? htonmemcpy(&tsize, &buffer[decode_pos], MVT_U32, 4);
#123?
?????????????????????????????????????????????? break;
#124?
??????????????????????????????????????? default:
#125?
?????????????????????????????????????????????? llerrs << "Attempting to read variable field with unknown size of " <<
#126?data_size << llendl;
#127?
?????????????????????????????????????????????? break;
#128?
??????????????????????????????????????? }
#129?
???????????????????????????????? }
#130?
???????????????????????????????? decode_pos += data_size;
#131?
#132?
???????????????????????????????? cur_data_block->addData(mvci.getName(), &buffer[decode_pos], tsize, mvci.getType());
#133?
???????????????????????????????? decode_pos += tsize;
#134?
????????????????????????? }
#135?
????????????????????????? else
#136?
????????????????????????? {
#137?
???????????????????????????????? // fixed!
#138?
???????????????????????????????? // so, copy data pointer and set data size to fixed size
#139?
???????????????????????????????? if ((decode_pos + mvci.getSize()) > mReceiveSize)
#140?
???????????????????????????????? {
#141?
??????????????????????????????????????? logRanOffEndOfPacket(sender, decode_pos, mvci.getSize());
#142?
#143?
??????????????????????????????????????? // default to 0s.
#144?
??????????????????????????????????????? U32 size = mvci.getSize();
#145?
??????????????????????????????????????? std::vector<U8> data(size);
#146?
??????????????????????????????????????? memset(&(data[0]), 0, size);
#147?
??????????????????????????????????????? cur_data_block->addData(mvci.getName(), &(data[0]),
#148?
??????????? ??????????????????????????????????????????????????????????????
#149?
???? size, mvci.getType());
#150?
???????????????????????????????? }
#151?
???????????????????????????????? else
#152?
???????????????????????????????? {
#153?
??????????????????????????????????????? cur_data_block->addData(mvci.getName(),
#154?
??????????????????????????????????????????????????????????????????????????
#155?
???? &buffer[decode_pos],
#156?
??????????????????????????????????????????????????????????????????????????
#157?
???? mvci.getSize(),
#158?
??????????????????????????????????????????????????????????????????????????
#159?
???? mvci.getType());
#160?
???????????????????????????????? }
#161?
???????????????????????????????? decode_pos += mvci.getSize();
#162?
????????????????????????? }
#163?
?????????????????? }
#164?
??????????? }
#165?
???? }
#166?
?
數(shù)據(jù)塊分析完成,后面就需要判斷這個數(shù)據(jù)包是否分析合法。
#167?
???? if (mCurrentRMessageData->mMemberBlocks.empty()
#168?
??????????? && !mCurrentRMessageTemplate->mMemberBlocks.empty())
#169?
???? {
#170?
??????????? lldebugs << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << llendl;
#171?
??????????? return FALSE;
#172?
???? }
#173?
#174?
???? {
#175?
??????????? static LLTimer decode_timer;
#176?
#177?
??????????? if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback())
#178?
??????????? {
#179?
?????????????????? decode_timer.reset();
#180?
??????????? }
#181?
#182?
??????????? {
#183?
?????????????????? LLFastTimer t(LLFastTimer::FTM_PROCESS_MESSAGES);
#184?
?????????????????? if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) )
#185?
?????????????????? {
#186?
????????????????????????? llwarns << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate-
#187?>mName << llendl;
#188?
?????????????????? }
#189?
??????????? }
#190?
#191?
??????????? if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback())
#192?
??????????? {
#193 ?
?????????????????? F32 decode_time = decode_timer.getElapsedTimeF32();
#194?
#195?
?????????????????? if (gMessageSystem->getTimingCallback())
#196?
?????????????????? {
#197?
????????????????????????? (gMessageSystem->getTimingCallback())(mCurrentRMessageTemplate->mName,
#198?
????????????????????????????????????????????????????? decode_time,
#199?
????????????????????????????????????????????????????? gMessageSystem->getTimingCallbackData());
#200?
?????????????????? }
#201?
#202?
?????????????????? if (LLMessageReader::getTimeDecodes())
#203?
?????????????????? {
#204?
????????????????????????? mCurrentRMessageTemplate->mDecodeTimeThisFrame += decode_time;
#205?
#206?
????????????????????????? mCurrentRMessageTemplate->mTotalDecoded++;
#207?
????????????????????????? mCurrentRMessageTemplate->mTotalDecodeTime += decode_time;
#208?
#209?
????????????????????????? if( mCurrentRMessageTemplate->mMaxDecodeTimePerMsg < decode_time )
#210?
????????????????????????? {
#211?
???????????????????????????????? mCurrentRMessageTemplate->mMaxDecodeTimePerMsg = decode_time;
#212?
????????????????????????? }
#213?
#214?
#215?
????????????????????????? if(decode_time > LLMessageReader::getTimeDecodesSpamThreshold())
#216?
????????????????????????? {
#217?
???????????????????????????????? lldebugs << "--------- Message " << mCurrentRMessageTemplate->mName << " decode took " <<
#218?decode_time << " seconds. (" <<
#219?
??????????????????????????????????????? mCurrentRMessageTemplate->mMaxDecodeTimePerMsg << " max, " <<
#220?
??????????????????????????????????????? (mCurrentRMessageTemplate->mTotalDecodeTime / mCurrentRMessageTemplate-
#221?>mTotalDecoded) << " avg)" << llendl;
#222?
????????????????????????? }
#223?
?????????????????? }
#224?
??????????? }
#225?
???? }
#226?
???? return TRUE;
#227?}
#228?
?
通過消息模板里的定義去解釋緩沖區(qū)里的數(shù)據(jù),然后就把這些字段加入到
cur_data_block
里,最后其它程序通過函數(shù)
LLTemplateMessageReader::getData
來獲取這個消息的字段數(shù)據(jù),這樣就達到第二人生客戶端與服務(wù)器交流的目的。
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
