青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 94, comments - 250, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

Nebula3學習筆記(6): 網絡系統

Posted on 2008-12-14 21:32 Condor 閱讀(1256) 評論(0)  編輯 收藏 引用

Nebula3的網絡子系統提供了基于TCP協議的簡單C/S通信模式. 它并沒有打算做成大廳,會話管理還有玩家數據同步的面向游戲的高級通信. 這些以后會在更高層的Nebula3子系統中出現.

使用IP地址

  一個IpAddress對象通過主機名字或TCP/IP地址加一個端口號定義了一個通信端點. IpAddress對象可以通過多數方式建立:

1: // 從 TCP/IP 地址和端口號:

2: IpAddress ipAddr("192.168.0.2",1234);

3:

4: // 從主機名和端口號:

5: IpAddress ipAddr("www.radonlabs.de",1234);

6:

7: // 從本機(127.0.0.1) 和端口號:

8: IpAddress ipAddr("localhost",1234);

9:

10: // 從"any" 地址 (0.0.0.0) 和端口號:

11: IpAddress ipAddr("any",1234);

12:

13: // 從廣播地址 (255.255.255.255) 和端口號:

14: IpAddress ipAddr("broadcast",1234);

15:

16: // 從主機的第一個合法網絡適配器的地址和端口號

17: IpAddress ipAddr("self",1234);

18:

19: // 從主機的第一個連接到互聯網的網絡適配器的地址和端口號:

20: IpAddress ipAddr("insetself",1234);

21:

22: // 從一個定義了主機名的URI和端口號:

23: IpAddress ipAddr(IO::URI("http://www.radonlabs.de:2100"));

  一個IpAddress對象可以用于從主機名查找TCP/IP地址:

1: IpAddress ipAddr("www.radonlabs.de",0);

2: String numericalAddr = ipAddr.GetHostAddr();

建立一個客戶端/服務器系統

  網絡子系統用TcpServer和TcpClient類實現了一個易用的基于TCP協議的C/S系統. 一個TcpServer可以為任意數量的TcpClient服務.

  建立一個服務器可以這么做:

1: using namespace Net;

2:

3: Ptr<TcpServer> tcpServer = TcpServer::Create();

4: tcpServer->SetAddress(IpAddress("any",2352));

5: if(tcpServer->Open())

6: {

7: // TcpServer successfully opened

8: }

  這樣會建立一個在2352端口監聽客戶端連接請求的服務器.

  為了跟TcpServer通信, 需要在客戶端建立一個TcpClient對象:

1: using namespace Net;

2:

3: Ptr<TcpClient> tcpClient = TcpClient::Create();

4: tcpClient->SetBlocking(false);

5: tcpClient->SetAddress(IpAddress("localhost",2352));

6: TcpClient::Result res = tcpClient->Connect();

  這里假設服務端和客戶端運行在同一臺機器上(因為客戶端連接到了”localhost”).

  像上面那樣非阻塞的情況, Connect()方法不是返回TcpClient::Success(這意味著連接建立好了)就是TcpClient::Connecting, 如果這樣的話, 應用程序需要繼續調用Connect()方法. 如果連接錯誤, 會返回一個TcpClient::Error的返回值.

  如果是阻塞的, Connect()方法直到連接建立(結果是TcpClient::Success)或發生錯誤才會返回.

  注意:一個交互式應用程序不應該在網絡通信時阻塞, 而應不斷地為用戶提供反饋.

  一旦連接建立, 服務端會為每個客戶機建立一個TcpClientConnection對象. TcpClientConnection在服務器上表示客戶機, 并且負責從客戶機收發數據.

  要進行接收和發送數據的話, 需使用IO::Stream對象. 在通信流上連接IO::StreamReader和IO::StreamWriter對象后, 從流中編碼和解碼數據是一件非常容易的事情.

  注意:發送數據并不是即時的, 而是在Send()方法被調用之前會一直保存在發送流當中.

  要客戶端給服務器發送一些文本數據話, 只要從發送流獲取一個指針, 向其中寫入數據后調用Send()方法就可以了:

1: using namespace Net;

2: using namespace IO;

3:

4: // obtain pointer to client's send stream and attach a TextWriter

5: const Ptr<Stream>& sendStream = tcpClient->GetSendStream();

6: Ptr<TextWriter> textWriter = TextWriter::Create();

7: textWriter->SetStream(sendStream);

8: textWriter->Open())

9: textWriter->WriteString("Hello Server");

10: textWriter->Close();

11:

12: // send off the data to the server

13: if(this->tcpClient->Send())

14: {

15: // data has been sent

16: }

  在服務器端接收客戶端數據, 應用程序需要要頻繁地(每幀一次)緩存帶有客戶羰數據的TcpClientConnection. 可能不只一個TcpClientConnection在等待處理, 因此處理循環應該像這樣:

1: // get array of client connections which received data since the last time

2: Array<Ptr<TcpClientConnection>> recvConns = tcpServer->Recv();

3: IndexT i;

4: for(i =0; i < recvConns.Size(); i++)

5: {

6: // get receive stream from current connection, attach a text reader and read content

7:      Ptr<TextReader> textReader = TextReader::Create();

8:      textReader->SetStream(recvConns[i]->GetRecvStream());

9:      textReader->Open();

10:      String str = textReader->ReadString();

11:      textReader->Close();

12:

13: // process received string and send response back to client

14: // create a TextWriter and attach it to the send stream of the client connection

15:      Ptr<TextWriter> textWriter = TextWriter::Create();

16:      textWriter->SetStream(recvConns[i]->GetSendStream());

17:      textWriter->Open();

18:      textWriter->WriteString("Hello Client");

19:      textWriter->Close();

20:

21: // finally send the response back to the client

22:      recvConns[i]->Send();

23: }

  在客戶端獲得服務器的應答, 調用TcpClient::Recv()方法會在數據到達之前一直阻塞(在阻塞模式下), 或者立即返回(在非阻塞模式下), 并在有服務器數據時返回true:

1: // check if data is available from the server

2: if(tcpClient->Recv())

3: {

4: // yep, data is available, get the recv stream and read the data from it

5: const Ptr<Stream>& recvStream = tcpClient->GetRecvStream();

6:      Ptr<TextReader> textReader = TextReader::Create();

7:      textReader->SetStream(recvStream);

8:      textReader->Open();

9:      String responseString = textReader->ReadString();

10:      n_printf("The server said: %s\n", responseString.AsCharPtr());

11:      textReader->Close();

12: }

  客戶端也應該通過調用IsConnected()訪求檢查連接是否有效. 如果因為某些原因使連接斷開, 這個方法會返回false.

  注意:

TcpServer和TcpClient并沒有為能夠跟不相關的客戶端和服務器端而實現一個潛在的通信協議(例如, 一個TcpServer可以跟標準的Web瀏覽器客戶端一起工作, 還有一個TcpClient類可以跟一個標準的HTTP服務器通信).

  現實世界的情況是, 一個應用程序應該實現自己的健壯的通信協議, 它至少會編碼負載數據的長度. 如果負載比最大包大小還要大, 數據會以多個包發送并在客戶端接收. 客戶端應該把數據解碼成一個完整的消息, 否則需要等待消息的數據接收完畢.

字節次序問題

  服務器和客戶端可能運行在不同字節次序的的CPU上. 如果二進制數據通過網絡發送, 數據必需轉換成兩個客戶端都一致的”網絡字節順序”. Nebula3在IO::BinaryReader和IO::BinaryWriter類中提供字節順序的自動轉換. 只需要簡單地調用下面的方法在網絡通信流上讀寫就可以了:

1: binaryReader->SetStreamByteOrder(System::ByteOrder::Network);

2: binaryWriter->SetStreamByteOrder(System::ByteOrder::Network);

Socket

  網絡子系統提供了一個把傳統socket函數包裝成C++接口的Socket類. 一般情況下應用程序不直接使用Socket類, 而是使用更高級的像TcpServer這樣的類. 但也不是不可能在有的時候直接使用socket函數比Socket類更方便.


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久偷看各类wc女厕嘘嘘偷窃| 亚洲综合丁香| 欧美精品一区二区三区在线播放| 久久精品女人天堂| 欧美在线视频观看| 久久久午夜电影| 久久久精品2019中文字幕神马| 久久精品道一区二区三区| 久久精品一区二区| 亚洲永久免费观看| 国产精品国产福利国产秒拍| 欧美日韩精品二区| 国产精品久线观看视频| 国产一区观看| 亚洲精品中文字幕有码专区| 一区二区高清在线观看| 亚洲欧美日韩中文视频| 久久综合五月| 欧美激情偷拍| 亚洲午夜免费福利视频| 欧美在线视频导航| 欧美精品videossex性护士| 国产精品国产三级国产专播品爱网| 国产美女扒开尿口久久久| 在线播放中文字幕一区| 一区二区三区高清在线观看| 久久精品国产69国产精品亚洲| 亚洲第一成人在线| 亚洲裸体视频| 久久久免费精品| 国产精品成人va在线观看| 狠狠噜噜久久| 亚洲欧美日韩一区二区三区在线观看 | 欧美日韩精品免费| 国产亚洲女人久久久久毛片| 日韩视频在线观看免费| 久久视频一区| 午夜久久99| 欧美日韩亚洲网| 在线观看国产精品网站| 欧美一区二区高清| 中文日韩欧美| 欧美理论在线| 亚洲人在线视频| 久久久人成影片一区二区三区| 一区二区三区产品免费精品久久75| 免费久久精品视频| 黄色一区二区三区| 欧美一区二区三区播放老司机 | 欧美网站在线| 亚洲麻豆一区| 亚洲大片在线观看| 久久亚洲综合网| 狠狠色狠狠色综合日日五| 欧美一区激情视频在线观看| 亚洲麻豆视频| 欧美日韩日韩| 久久gogo国模裸体人体| 亚洲视频在线免费观看| 欧美日韩1区2区| 一本色道久久综合亚洲精品按摩 | 一区二区日韩| 亚洲日本中文字幕区| 欧美激情五月| 亚洲小说春色综合另类电影| 日韩亚洲一区二区| 欧美视频官网| 校园春色国产精品| 欧美在线一区二区三区| 在线日韩成人| 亚洲精品国产无天堂网2021| 欧美乱大交xxxxx| 亚洲一区中文| 亚洲欧美国产高清| 国产三级欧美三级| 欧美va亚洲va国产综合| 欧美大片一区二区三区| 亚洲午夜羞羞片| 性欧美18~19sex高清播放| 国内精品久久久久影院 日本资源 国内精品久久久久伊人av | 欧美极品在线视频| 亚洲伊人久久综合| 欧美专区在线播放| 亚洲激情小视频| 久久精品国产一区二区三区免费看| 国产亚洲精品高潮| 99在线精品视频在线观看| 一区二区在线视频观看| 久久综合电影| 羞羞色国产精品| 国产精品久久久久9999高清| 亚洲高清电影| 欧美日韩一区二区三区在线观看免 | 欧美中文在线视频| 精品福利免费观看| 亚洲人成高清| 国产欧美日韩三区| 91久久精品www人人做人人爽| 香蕉久久夜色精品国产使用方法| 99视频+国产日韩欧美| 欧美视频在线一区二区三区| 久久久久国产成人精品亚洲午夜| 欧美激情五月| 久久精品官网| 欧美日韩一区免费| 免费人成精品欧美精品| 国产精品麻豆成人av电影艾秋| 久久先锋资源| 国产精品私拍pans大尺度在线| 免费观看成人网| 国产欧美日韩不卡免费| 日韩小视频在线观看| 亚洲黄色毛片| 久久久久成人精品免费播放动漫| 亚洲欧美日韩国产成人| 欧美日韩一级黄| 亚洲人久久久| 亚洲欧洲日本专区| 久久久av毛片精品| 久久激情久久| 国产欧美精品va在线观看| 亚洲老板91色精品久久| 亚洲国产成人久久综合| 久久久久国产免费免费| 久久成人精品无人区| 国产精品色婷婷久久58| 亚洲调教视频在线观看| 亚洲一级电影| 欧美日韩亚洲一区二区三区在线观看 | 亚洲一区二区三区在线看| 一区二区三区四区在线| 欧美国产综合视频| 最新国产精品拍自在线播放| 91久久精品一区二区三区| 久久精品免费| 裸体素人女欧美日韩| 激情成人综合网| 久久青草欧美一区二区三区| 久久久国产一区二区| 国产一区二区高清| 午夜欧美不卡精品aaaaa| 久久精品国产亚洲精品| 韩日欧美一区二区| 久久国产精品99久久久久久老狼| 欧美在线观看日本一区| 国产午夜精品理论片a级探花| 亚洲欧美另类中文字幕| 久久精品青青大伊人av| 韩国福利一区| 美国十次了思思久久精品导航| 免费在线亚洲欧美| 亚洲激情午夜| 欧美日韩国产丝袜另类| 99re6热在线精品视频播放速度| 亚洲毛片在线| 欧美日韩喷水| 亚洲欧美日本日韩| 老司机免费视频一区二区| 在线观看国产成人av片| 欧美精品九九| 一区二区三区四区五区精品| 久久激情中文| 91久久综合| 国产精品日韩| 在线 亚洲欧美在线综合一区| 欧美成人一区二区三区在线观看 | 亚洲在线中文字幕| 国产日韩一区| 久久免费一区| 日韩一区二区电影网| 久久精品免费电影| 亚洲精品偷拍| 国产精品嫩草99av在线| 久热精品视频在线观看一区| 亚洲国产精品一区二区第一页| 亚洲一二区在线| 1769国内精品视频在线播放| 欧美欧美在线| 久久久久在线观看| 亚洲伊人伊色伊影伊综合网| 欧美二区在线观看| 久久精品视频在线观看| 一区二区日韩免费看| 伊人婷婷久久| 国产欧美91| 欧美激情视频一区二区三区免费| 欧美在线啊v一区| 一本色道**综合亚洲精品蜜桃冫| 美女黄毛**国产精品啪啪| 羞羞色国产精品| 9久草视频在线视频精品| 国产亚洲毛片在线| 欧美午夜视频在线| 欧美激情欧美狂野欧美精品 | 欧美日韩国产二区| 麻豆9191精品国产| 久久福利影视| 香蕉久久夜色| 亚洲小视频在线| 夜夜狂射影院欧美极品|