1. 程式人生 > >[網路開發]RakNet翻譯文件(6)

[網路開發]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的資料時使用。