[網路開發]RakNet翻譯文件(6)
Bitstream概述
Bitstream類是一個RakNet名稱空間下的helper類,是一個用於打包、解包bits的動態陣列。它有如下四個優點:
1.動態的建立資料包
2.壓縮
3.寫入Bits
4.位元組序轉化
對於結構體打包來說,需要預定義結構體,並將他們轉化為一個(char*)的型別。使用Bitstream,你可以在執行時根據上下文選擇寫入資料塊。Bitstreams可以使用SerializeBitsFromIntegerRange()和SerializeFloat16()函式壓縮原有的資料型別。
當然了,你還可以寫入Bits。大多數時間下你不需要關心這些事情。然而,當寫入布林值時它會自動僅僅寫入一個Bit位。這種方式在加密中非常有效,因為你的資料不再是按照位元組對齊。(譯者注:使得破解者無法獲取你的資料結構)
寫入資料
Bitstream是一個可以帶任何資料型別的模板類。如果是一個內建的資料型別(譯者注:指的是非自定義的資料型別),例如NetworkIDObject,它使用了局部模板特化來更有效的寫入資料型別。如果它是一個原生型別或者一個結構體,他寫入一個單獨的bits,與memcpy()有些類似。你可以傳遞包含多個數據成員的結構體給bitstreams。然後,你需要序列化每一個單獨的元素以糾正位元組序。(例如:在PC和Mac之間通訊需要如此)
struct MyVector { float x,y,z; } myVector; // 沒有位元組序交換 bitStream.Write(myVector); // 有位元組序交換 #undef __BITSTREAM_NATIVE_END bitStream.Write(myVector.x); bitStream.Write(myVector.y); bitStream.Write(myVector.z); // 你可以過載左移右移操作符 // 右移操作符必須在RakNet名稱空間裡,或者使用BitStream.h中的名稱空間代替。 // 使用std::string會引起一些錯誤 namespace RakNet { RakNet::BitStream& operator << (RakNet::BitStream& out, MyVector& in) { out.WriteNormVector(in.x,in.y,in.z); return out; } RakNet::BitStream& operator >> (RakNet::BitStream& in, MyVector& out) { bool success = in.ReadNormVector(out.x,out.y,out.z); assert(success); return in; } } // RakNet名稱空間 // 從BitStream中讀取 myVector << bitStream; // 寫入BitStream myVector >> bitStream;
可選的 —— 其中的一個建構函式是以位元組長度為引數。如果你清楚傳遞的資料長度,你可以傳遞這個數給Bitstream的建構函式,可以避免建立bitstream時內部動態重新分配記憶體。
參見Creating Packets獲得更多的細節。
讀取資料
讀取資料相對簡單。建立一個bitstream,在建構函式中指定你的資料。
// 假設我們已經有了一個 Packet *物件 BitStream myBitStream(packet->data, packet->length, false); struct MyVector { float x,y,z; } myVector; // 沒有位元組序交換的 bitStream.Read(myVector); // 有位元組序交換的 (RakNetDefines.h中的__BITSTREAM_NATIVE_END巨集必須被註釋掉) #undef __BITSTREAM_NATIVE_END #include "BitStream.h" bitStream.Read(myVector.x); bitStream.Read(myVector.y); bitStream.Read(myVector.z);
參見 Receiving Packets 獲得完整的例子。
序列化資料
你可以通過使用BitStream::Serialize()替代Read()或者Write(),這樣就可以使用相同的讀寫函數了。
struct MyVector { float x,y,z; // writeToBitstream==true 表示寫資料 writeToBitstream==false 表示讀資料 void Serialize(bool writeToBitstream, BitStream *bs) { bs->Serialize(writeToBitstream, x); bs->Serialize(writeToBitstream, y); bs->Serialize(writeToBitstream, z); } } myVector;
參見 Receiving Packets 獲得完整的例子。
有用的函式
參見BitSteam.h可以獲得完整的函式列表
Reset 函式
重置位元組流,清空所有資料
Write 函式
寫入函式在位元組流的結尾將資料寫入。你應該使用類似的Read函式從bitstream中讀取資料
Read 函式
讀取函式按照從頭到尾的順序讀取bitstream中已經存在的資料。如果bitstream中沒有任何資料,Read函式返回false。
WriteBitsFromIntegerRange, ReadBitsFromIntegerRange,SerializeBitsFromIntegerRange 函式
如果一個數字知識使用的特殊的值區間(例如 10-20),當位元數寫入那個值區間內,這個函式將會自動。
WriteCasted, ReadCasted 函式
寫一個型別的變數,當他需要被轉化為其他資料型別。例如:WriteCasted< char >( 5 )等同於 char c = 5; Write( c );
WriteNormVector, ReadNormVector 函式
寫入一個常規的向量,其中每一個元素的範圍都是-1 — 1。每一個元素有16位。
WriteFloat16, ReadFloat16 函式
給出浮點數的最大最小值,以65535劃分區間,將結果寫入到一個16位元組裡(精度有損)。
WriteNormQuat, ReadNormQuat 函式
寫入一個四元數到16 * 3 + 4位資料中(精度有損)。
WriteOrthMatrix, ReadOrthMatrix 函式
轉化一個正交矩陣為四元數,然後呼叫WriteOrthMatrix/ReadOrthMatrix函式
GetNumberOfBitsUsed, GetNumberOfBytesUsed
給出已寫入的位元組或者位的大小。
GetData 函式
給出bitstream內部資料的指標。他是一個由malloc分配的(char*)指標,在你需要直接訪問bitstream的資料時使用。