1. 程式人生 > >[網路開發]RakNet文件翻譯(2)

[網路開發]RakNet文件翻譯(2)

Connecting to other systems

找到連線的物件

下面是5種連線到其他系統的方法:

1.直接通過IP地址(前提是你已經知道該IP)

2.LAN廣播

3.使用雲伺服器或者雲客戶端外掛

4.使用大廳伺服器或者房間外掛(譯者注:型別與遊戲大廳和遊戲房間的模式,想想QQ棋牌遊戲)

5.使用DirectoryServer.php

方法1:直接使用IP地址

從編碼的角度來說,最簡單最容易的方法是硬編碼的IP地址或者域名或者給出一個GUI要求使用者輸入他們相連線到其他系統的IP地址,大部分例子使用此方法。回顧網路遊戲剛剛出現的時候使用此方法,也是當時唯一可用的方法。

優點:

  • 對程式設計師或者美工來說很簡單,GUI介面可以很簡單
  • 如果IP地址或者域名是固定的,例如你運行了一個專用伺服器,這是一個正確的解決方案。

缺點:

  • 不夠靈活
  • 使用者只能與他們認識的人玩遊戲

注意:在同一臺電腦或者相同的應用程式,可以使用127.0.0.1或者 localhost連線到另外一個RakPeer例項。

方法2:區域網廣播

RakNet支援廣播一個數據包找到本地區域網內其他系統的功能,使用可選的資料包傳送和檢測應用程式,LANServerDiscovery例子展示了這個技術。

在RakPerrInterface.h中,Ping函式可以試下如下個功能

rakPeer->Ping( "255.255.255.255", REMOTE_GAME_PORT,
onlyReplyOnAcceptingConnections );

REMOTE_GAME_PORT可以是你關心的應用程式執行在其他系統上的任何埠。onlyReplyOnAcceptingConnections 是一個標誌其他系統是否應該答覆的布林值,即使你沒有連線到其他系統上的可用連線。

開放系統將會用ID_UNCONNECTED_PONG,看看下面的例子:

if (p->data[0]==ID_UNCONNECTED_PONG)
{
    RakNet::TimeMS time;
    RakNet::BitStream bsIn(packet->data,packet->length,false);
    bsIn.IgnoreBytes(1);
    bsIn.Read(time);
    printf("Got pong from %s with time %i\n", p->systemAddress.ToString(),
RakNet::GetTime() - time);
}

為了傳送使用者自定義資料,呼叫 RakPeer::SEtOfflinePingResponse( customUserData, lengthInBytes ); RakNet將會拷貝傳給他的資料,同時返回值追加到ID_UNCONNECTED_PONG。(譯者注:猜想是以位與的方式)

注意:在RakPeer.cpp中定義了一個硬編碼的MAX_OFFLINE_DATA_LENGTH長度,它限制了使用者資料長度。如果你的資料超過這個定義,修改該值並且重編譯。

優點:

  • 你可以在程式啟動的時候自動的加入遊戲,不需要GUI或者其他使用者互動
  • 在區域網內發現遊戲的最佳方式

缺點:

  • 在一般的Internet網路上沒用
  • 不如輕量級資料庫外掛靈活。

方法3:使用 雲伺服器/雲客戶端 外掛

雲伺服器/雲客戶端不需要修改可直接作為伺服器目錄。

方法4:使用大廳伺服器或者房間外掛

大廳伺服器為玩家互動和啟動遊戲提供了一個數據庫驅動服務。它提供了一些功能,例如朋友,配對,郵件,排名,即時通訊,快速匹配,房間和房間調整。

LobbyServerTest和LobbyClientTest例子展示瞭如何使用該功能。

優點:

  • 對於加油遊戲的玩家來說比較靈活
  • 允許使用者在啟動遊戲之前進行互動
  • 建立聯絡
  • 支援多個標題(稱號)

缺點:

  • 需要一個單獨並且專用的伺服器來承載該外掛,並且伺服器需要資料庫支援
  • 相比一個簡單的遊戲列表來說,該功能需要一個相對較大的並且複雜,需要在時間和程式設計上投入更多。

方法5:DirectoryServer.php

DirectoryServer.php 和相關的程式碼可以在Samples\PHPDirectoryServer2中找到。通過你的Web伺服器去儲存一個遊戲的上傳,同時該遊戲是基於字串的資訊,這種給出遊戲列表的方法比較廉價。要獲得更多的資訊,請檢視該功能的使用者手冊。

優點:

  • 不需要一臺專用的伺服器,只需要一個網頁
  • 缺點:

不夠靈活

  • 有時候不可用(可能需要多次查詢請求)

嘗試啟動連結

一旦你知道了你要連線到的遠端系統的IP地址,使用RakPeerInterface::Connect()嘗試啟動非同步的連線,連線引數如下:

ConnectionAttemptResult Connect( const char* host, unsigned short remotePort,
const char *passwordData, int passwordDataLength, PublicKey *publicKey=0,
unsigned connectionSocketIndex=0, unsigned sendConnectionAttemptCount=6,
unsigned timeBetweenSendConnectionAttemptsMS=1000, RakNet::TimeMS timeoutTime=0 ) ;
  • host 是一個IP地址或者域名
  • remotePort 是一個遠端系統監聽的埠,你傳遞給Startup()函式的埠
  • passwordData 是隨著連線請求傳送可選的二進位制資料。如果該資料與傳遞給RakPeerInterface::SetPassword()函式的引數內容不匹配,遠端系統會迴應ID_INVALID_PASSWORD
  • passwordDataLength是passwordData的長度,單位是Byte
  • publicKey是遠端系統上一個傳遞給InitializeSecurity()函式的公共鍵值。如果你不想使用,傳0值
  • connectionSocketIndex是一個傳遞給RakPeer::Startup()中確定要傳送的socket描述符陣列中的索引.
  • sendConnectionAttempyCount是在放棄連線之前嘗試傳送的資料包次數。這是用於三種不同MTU大小的檢測。預設值為12以為著每個MTU傳送4次,這應該適合於任何形式的丟包了。值越低意味著收到ID_CONNECTION_ATTEMPT_FAILED越快。
  • timeBetweenSendConnectionAttemptsMS是指傳送下一個連線嘗試的間隔毫秒數。4倍的ping值是比較好的。
  • timeOutTime是這次特別的連線中一條訊息丟失遠端系統之前等待的毫秒數,(譯者注:其實就是無響應超時時間)。預設值為0意味著使用從SetTimeOutTime()中得到的全域性值。
  • Connect()如果嘗試連線成功則會返回CONNECTION_ATTEMPT_STARTED,其他返回值都是失敗的。

注意:Connect()函式返回true並不意味著你已經連線上了。如果連線成功你會收到ID_CONNECTION_REQUEST_ACCEPTED 訊息,否則你會收到其他的錯誤訊息。

連線訊息作為Packet::data結構的第一個位元組返回

連線關閉: ID_DISCONNECTION_NOTIFICATION, ID_CONNECTION_LOST
新的連線: ID_NEW_INCOMING_CONNECTION, ID_CONNECTION_REQUEST_ACCEPTED
嘗試連線失敗: ID_CONNECTION_ATTEMPT_FAILED, ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY, ID_OUR_SYSTEM_REQUIRES_SECURITY, ID_PUBLIC_KEY_MISMATCH, ID_ALREADY_CONNECTED, ID_NO_FREE_INCOMING_CONNECTIONS, ID_CONNECTION_BANNED, ID_INVALID_PASSWORD, ID_INCOMPATIBLE_PROTOCOL_VERSION, ID_IP_RECENTLY_CONNECTED

ID_CONNECTION_ATTEMPT_FAILED故障排除

ID_CONNECTION_ATTEMPT_FAILED是通用的訊息,他以為這沒有建立與遠端系統的溝通。可能的原因如下:

  • IP地址錯誤
  • 對方的系統可能沒有執行RakNet或者沒有呼叫RakPeerInterface::Startup()
  • 遠端系統已經開始了RakNet,但是沒用呼叫RakPeerInterface()::SetMaximumIncomingConnections()
  • 遠端系統的防火牆阻止了你所選擇埠上的UDP包
  • 遠端系統上的路由器阻止了你所選擇埠上的UDP包,檢視NAT Punchthrough外掛解決該問題
  • 在Windows Vista,網路驅動安全服務有時候會斷掉UDP,並不是針對Raknet的,而是針對所有UDP連線,甚至是DirectPlay。該服務應該被回滾或者不要安裝。
  • 開啟了安全連線,並且你的系統安全檢查失敗
  • 你的IP地址在RakPeerInterface::AddToBanList()函式中被禁用了。注意一些外掛,例如有自動禁用IP地址功能的Connection filter外掛。

假設你已經連線上了,請轉向下一部分:Createing Packets