RakNet
一个facebook开源的网络游戏框架,有些游戏在用。
然后走Send_Windows_Linux_360NoVDP调用windows sendto 第一个数据包长度为4,数据为0
正常发送数据的话,数据包先进队列。
void RakPeer::SendBuffered( const char *data, BitSize_t numberOfBitsToSend, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast, RemoteSystemStruct::ConnectMode connectionMode, uint32_t receipt )
{
BufferedCommandStruct *bcs;
// 这地方Allocate用的是内存池
bcs=bufferedCommands.Allocate( _FILE_AND_LINE_ );
// 但是这地方每次发送都分配一次?
bcs->data = (char*) rakMalloc_Ex( (size_t) BITS_TO_BYTES(numberOfBitsToSend), _FILE_AND_LINE_ ); // Making a copy doesn't lose efficiency because I tell the reliability layer to use this allocation for its own copy
if (bcs->data==0)
{
notifyOutOfMemory(_FILE_AND_LINE_);
bufferedCommands.Deallocate(bcs, _FILE_AND_LINE_);
return;
}
RakAssert( !( reliability >= NUMBER_OF_RELIABILITIES || reliability < 0 ) );
RakAssert( !( priority > NUMBER_OF_PRIORITIES || priority < 0 ) );
RakAssert( !( orderingChannel >= NUMBER_OF_ORDERED_STREAMS ) );
memcpy(bcs->data, data, (size_t) BITS_TO_BYTES(numberOfBitsToSend));
bcs->numberOfBitsToSend=numberOfBitsToSend;
bcs->priority=priority;
bcs->reliability=reliability;
bcs->orderingChannel=orderingChannel;
bcs->systemIdentifier=systemIdentifier;
bcs->broadcast=broadcast;
bcs->connectionMode=connectionMode;
bcs->receipt=receipt;
bcs->command=BufferedCommandStruct::BCS_SEND;
bufferedCommands.Push(bcs);
if (priority==IMMEDIATE_PRIORITY)
{
// Forces pending sends to go out now, rather than waiting to the next update interval
quitAndDataEvents.SetEvent();
}
}
UpdateNetworkLoop线程会不断的从数据包队列中取出数据发送 10ms处理一次
RecvFromLoop定义在RakNetSocket2.cpp,f12跳转不到这里。
binding.eventHandler->OnRNS2Recv(recvFromStruct);
...
PushBufferedPacket(recvStruct);
quitAndDataEvents.SetEvent();
WireShark直接支持RakNet协议的解析(但是必须在服务器与客户端握手之前开启捕获,才能识别出RakNet协议)。
wiki上对RakNet协议的介绍。 https://wiki.vg/Raknet_Protocol
84开头的包,前14个字节都跟网络引擎有关,第15个字节开始跟特定消息有关。
粘包
RakPeer继承于RakPeerInterface,接口类内全是纯虚函数