这篇文章介绍基于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