天天看點

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