[網路開發]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