Raknet入门简单实例分析(1)

这篇文章介绍基于Raknet客户端和服务端的简单实现。

目标:建立控制台程序Server和Client实现文本数据传输

 

为什么要写这篇文章?因为官方给提供的例子不够简单!对于基础薄弱的,像我这样的童鞋,搞起来比较费劲。目的在于尽快上手,可以使用这个库完成简单的通信功能。

 

暂时还没有去读Raknet源代码,所以所得结论都是我调试所看到结果的猜测。不一定准确,只供入门简单理解。

若有不当之处,请各位高手批评指正。

 

假设读者具备基础:

1 VC++环境非常熟悉

2 使用过socket API可以开发简单的文本通信程序

 

进入正题!

一. 编程准备

首先下载Raknet源代码,编译之后,拿到lib和dll文件。本人使用Raknet3.717版本,相对较新,官方4.0版本和这个差不多。头文件,原型定义几乎一样的。

打开sln文件(vs2010)编译后,可在lib目录里找到RakNetLibStaticDebug.lib文件,将其加入到自己的工程目录里(源码目录)。

另外此例需要以下三个头文件,从Source文件夹里找到,并加入到自己的工程文件夹里。

#include "MessageIdentifiers.h"
#include "RakPeerInterface.h"
#include "RakNetTypes.h"

至于这三个头文件干什么用的,到时候自己写代码的时候,鼠标放到函数上,go to definition会跳转到这几个头文件内部,简单说,就是一些函数和类的声明!

 

在程序中需要加入lib库文件,推荐如下加入,(最好在stdafx.h里)

#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib , "lib\\RakNetLibStaticDebug.lib")

 

OK,以上便是使用Raknet进行网络程序开发的准备了,下面进入代码解析部分。

 

二. 服务端Server

//创建一个实例

 RakNet::RakPeerInterface *server = RakNet::RakPeerInterface::GetInstance();

//创建套接字描述,也就是指定一个通信端口(UDP无监听)
 RakNet::SocketDescriptor socketDescriptor;
 socketDescriptor.port = 30050;

//启动服务端
 bool b = server->Startup(2, &socketDescriptor, 1 )==RakNet::RAKNET_STARTED;

//如果没有报错,服务端启动成功了。
 RakAssert(b);

//设置最大连接数(此连接并不等同TCP的连接!),这一步必须设置,否则会出现客户端调用Connect失败
 server->SetMaximumIncomingConnections(2);

 

接下来就是处理数据发送接收的部分了

while(1)

{
  packet = server->Receive();
  if(packet)

  {

    switch(packet->data[0])

    {

//用户自定义数据包的接收处理,此处显示接到的数据包内容。其他消息的处理可以同样用case语句

      case ID_USER_PACKET_ENUM:
       printf("接收到自定义数据,内容:%s\n",packet->data);
      break;

      default:

      break;

    }

  }

以上是简单的数据接收并显示的处理程序。下面是客户端了,比较简单

 

三. 客户端

//这部分参见服务端部分

 RakNet::RakPeerInterface *client = RakNet::RakPeerInterface::GetInstance();
 RakNet::SocketDescriptor socketDescriptor;
 socketDescriptor.port = 0;
 client->Startup(1, &socketDescriptor, 1 );

//客户端连接服务端,判断返回值和RakNet::CONNECTION_ATTEMPT_STARTED是否相等,相等只是代表请求投递成功,并不意味着服务端接收了连接请求。
 bool rs = (client->Connect("127.0.0.1", 30050, NULL, 0, 0)== RakNet::CONNECTION_ATTEMPT_STARTED);
 RakNet::Packet *packet;
 bool bIsConn = false;

//循环接收来自服务端的消息
 while(1)
 {
  packet = client->Receive();
  if(packet)
  {

//当接收到的消息的第一个字节的数据为ID_CONNECTION_REQUEST_ACCEPTED才表示服务端接受了连接请求!!!
   if( packet->data[0] == ID_CONNECTION_REQUEST_ACCEPTED )
   {
    bIsConn = true;
    printf("connect is ok\n");
    char flag = ID_USER_PACKET_ENUM;
    char buffer[] = " hello server, the message from client\n";
    buffer[0]=flag;

//连接ok后发送一个字符串到服务端
    uint32_t sendrs = client->Send((const char*)buffer,

           strlen(buffer)+1,HIGH_PRIORITY,RELIABLE_ORDERED,0,

           RakNet::UNASSIGNED_SYSTEM_ADDRESS,true);
    printf("send return: %d\n",sendrs);
   }

//如果没有连接成功,则继续连接,直到服务端返回的信息告诉我们连接成功了
   if( !bIsConn )
   {
    printf("connect failed\n");
    client->Connect("127.0.0.1", 30050, NULL, 0, 0);
   }
  }
 }

 

基本情况就是这样,我也是研究官方提供的例子ServerClientTest2 搞了好几天才搞出来这么个例子。走了不少弯路吧,就是觉得这个例子是所有例子中比较简单的,即使这样,我觉得看起来还是费劲,所以自己搞了一个更简单的,来入门。 欢迎有兴趣的童鞋一起交流,学习,进步。 QQ:7278449

Raknet是一个基于UDP网络传输协议的C++网络库,允许程序员在他们自己的程序中实现高效的网络传输服务。通常情况下用于游戏,但也可以用于其它项目。   Radnet有以下特点:   l 高性能 在同一台计算机上,Raknet可以实现在两个程序之间每秒传输25,000条信息;   l 容易使用 Radnet有在线用户手册,视频教程。每一个函数和类都有详细的讲解,每一个功能都有自己的例程;   l 跨平台,当前Radnet支持Windows, Linux, Macs,可以建立在Visual Studio, GCC, Code: Blocks, DevCPP 和其它平台上;   l 在线技术支持 RakNet有一个活跃的论坛,邮件列表,你只要给他们发信,他们可以在几小时之内回复你。   l 安全的传输 RakNet在你的代码中自动使用SHA1, AES128, SYN,用RSA避免传输受到攻击   l 音频传输 用Speex编码解码,8位的音频只需要每秒500字节传输。   l 远程终端 用RakNet,你能远程管理你的程序,包括程序的设置,密码的管理和日志的管理。   l 目录服务器 目录服务器允许服务器列举他们自己需要的客户端,并与他们连接。   l Autopatcher Autopatcher系统将限制客户端传输到服务端的文件,这样是为了避免一些不合法的用户将一些不合法的文件传输到服务端。   l 对象重载系统   l 网络数据压缩 BitStream类允许压缩矢量,矩阵,四元数和在-1到1之间的实数。   l 远程功能调用   l 强健的通信层 可以保障信息按照不同的信道传输   RakNet支持两种版权,如果你是做免费游戏,RakNet将是免费的。相反,你必须支付一定的费用。   从这里你可以下载到最新的RakNet:   http://www.rakkarsoft.com/raknet/downloads/RakNet.zip   例子:   #include   #include   #include   #include "RakClientInterface.h" //建立客服端所需要的信息,其中包括客服端的建立,连接和数据的发送和接收   #include "RakNetworkFactory.h" //用于管理我们在程序中使用的类,包括类内存分配和类内存的释放   #include "RakServerInterface.h" //用于建立服务器所需用的信息,包括服务器的建立,连接和数据的发送和接收   #include "PacketEnumerations.h" //用于处理网络引擎在运行过程中得到的信息   Packet *packet;//网络传输中用于存储数据的一个数据结构   /////////////////////////////////////////////////////   /*   Struct Packet   {   PlayerID playerId; //表明了包的出处。每一个连接服务器的客户端都将被分配一个唯一的ID号,用于标识自己。   Unsigned long length; //数据长度   Unsigned long bitsize; //比特大小   Char *data; //包中的数据   }   */   /////////////////////////////////////////////////////   int main(void)   {   char str[512];   RakClientInterface *rakClientInterface;   RakServerInterface *rakServerInterface;   printf("(C)客服端 (S)服务器?\n");   gets(str);   if (str[0]=='c')   {   rakClientInterface=RakNetworkFactory::GetRakClientInterface();//初始化一个客户端实例,为它分配内存   rakServerInterface=0;   printf("客服端已经建立。");   }   else   {   rakClientInterface=0;   rakServerInterface=RakNetworkFactory::GetRakServerInterface();//初始化一个服务器实例,为它分配内存   printf("服务器已经建立。");   }   if (rakServerInterface)   {  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值