RakNet是一款很优秀的可移植的网络引擎。以高效率著称。
在一般的局域网游戏中(比如CS、魔兽争霸),需要玩家建立一个主机,
然后在局域网内其他玩家发现这个主机,加入主机后玩家会在一个房间里。这时候主机可以发动游戏,其他玩家都会进入相同的场景进行角逐。每个玩家在场景中的变化其他玩家都需要知道并且得到相应的改变。这其中就用到了远程调用的原理。
下面是用RakNet实现一个简单的远程调用控制台程序:
需要使用RakNet4版本的SDK:
#include
#include "raknet/RakPeerInterface.h"#include
"raknet/MessageIdentifiers.h"#include "raknet/BitStream.h"#include
"raknet/RakNetTypes.h"#include "raknet/RPC4Plugin.h"#define
MAX_CLIENTS 10#define SERVER_PORT 60000void
printMsg(RakNet::BitStream* bitstream, RakNet::Packet*
packet){printf("hello world!天泽秀敏的博客/n");}int main(void){char
str[512];RakNet::RakPeerInterface* peer =
RakNet::RakPeerInterface::GetInstance();RakNet::Packet* packet;bool
isServer;RakNet::RPC4 rpc1,
rpc2;printf("(C)or(S)erver/n");gets(str);if((str[0] == 'c') ||
(str[0] == 'C')){peer->Startup(1,
&RakNet::SocketDescriptor(),
1);peer->AttachPlugin(&rpc1);rpc1.RegisterFunction("printMsg",
printMsg);isServer = false;}else{peer->Startup(MAX_CLIENTS,
&RakNet::SocketDescriptor(SERVER_PORT, 0),
1);peer->AttachPlugin(&rpc2);isServer =
true;}if(isServer){printf("Starting the
Server./n");peer->SetMaximumIncomingConnections(MAX_CLIENTS);}else{printf("Enter
Server IP or hit enter for 127.0.0.1/n");gets(str);if(str[0] ==
0){strcpy(str, "127.0.0.1");}printf("Starting the
Client./n");peer->Connect(str, SERVER_PORT, 0, 0);}while(1)for
(packet=peer->Receive(); packet;
peer->DeallocatePacket(packet),
packet=peer->Receive()){switch (packet->data[0]){case
ID_REMOTE_DISCONNECTION_NOTIFICATION:printf("Another client has
disconnected./n");break;case
ID_REMOTE_CONNECTION_LOST:printf("Another client has lost the
connection./n");break;case
ID_REMOTE_NEW_INCOMING_CONNECTION:printf("Another client has
connected./n");break;case
ID_CONNECTION_REQUEST_ACCEPTED:{printf("Our connection request has
been accepted./n");break;}case ID_NEW_INCOMING_CONNECTION:printf("A
connection is incoming./n");if(isServer){rpc2.Call("printMsg", 0,
HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);}break;case
ID_NO_FREE_INCOMING_CONNECTIONS:printf("The server is
full./n");break;case ID_DISCONNECTION_NOTIFICATION:if
(isServer){printf("A client has disconnected./n");} else
{printf("We have been disconnected./n");}break;case
ID_CONNECTION_LOST:if (isServer){printf("A client lost the
connection./n");} else {printf("Connection
lost./n");}break;default:printf("Message with identifier %i has
arrived./n",
packet->data[0]);break;}}RakNet::RakPeerInterface::DestroyInstance(peer);}
基本流程是www.huayipenquan.com,昱昱炎炎:写一些客户端、服务端都需要的振乾方宁的博客函数,就是上面的printMsg, 函数的参数必须是上面所示的2项。
--》然后在服务端和客户端都声明一个PRC4, 把对应的服务端或者客户端的Peer绑定RPC4插件
--》在服务端或者客户端分别注册自己供外界调用的函数
--》然后假设你需要在客户端程序的某个地方调用服务端的代码,只需要在这个地方调用一个注册的唯一标识的函数名称,就可以远程调用那个函数了。
在局域网对战中,发现服务器可以这样实现:
mClient->Ping("255.255.255.255", mServerPort, true);
客户端Ping给广播地址,
这样可以对存在的服务器地址传来的Pong进行反应。在客户端如果得到一个连接允许的消息,那么就表示连接上了服务器。
进入房间后玩家相互聊天的实现也很简单。客户端远程调用服务器的一个函数,并且调用之前把聊天内容通过RakNet4的BitStream发送出去,服务端通过读取BitStream然后把聊天内容广播给各个客户端,这样一个客户端输入的内容整个房间里的人都能看见。
至于进入场景后的玩家之间的数据同步也是一样的道理。通过远程调用服务端,服务端广播数据,客户端再实时更新。