- OpenGL ES 3.x游戲開發(fā)(上卷)
- 吳亞峰
- 1840字
- 2019-01-05 00:53:39
2.5 Socket網(wǎng)絡(luò)通信
伴隨著移動互聯(lián)網(wǎng)的高速增長,智能手機上的游戲娛樂應(yīng)用也逐步由單機向網(wǎng)絡(luò)化方向發(fā)展。因此,對于Android開發(fā)人員來說,開發(fā)具有網(wǎng)絡(luò)功能的應(yīng)用程序成為了一項必備的技能。本節(jié)將向讀者介紹網(wǎng)絡(luò)開發(fā)中非常重要的一項技術(shù),Socket(網(wǎng)絡(luò)套接字)應(yīng)用開發(fā)。
2.5.1 Socket開發(fā)基本知識
網(wǎng)絡(luò)應(yīng)用程序的開發(fā)也有很多不同的架構(gòu)與模式,常見的有B/S、C/S等,Socket主要是用于進(jìn)行傳統(tǒng)的C/S模式應(yīng)用的開發(fā)。C/S模式中主要需要開發(fā)兩個端,服務(wù)端與客戶端,其基本的工作原理如圖2-24所示。
從圖2-24中可以看出,C/S模式通信的基本過程如下。

▲圖2-24 C/S模式通信的基本原理
(1)首先啟動服務(wù)器,監(jiān)聽指定端口,等待接收客戶端的連接請求。
(2)客戶端請求連接到服務(wù)器的指定端口。
(3)服務(wù)器收到客戶端的連接請求,建立連接。
(4)客戶端和服務(wù)器同時各打開一個輸入流和輸出流,客戶端的輸出流與服務(wù)器的輸入流連接,服務(wù)器的輸出流與客戶端的輸入流連接。
(5)客戶端與服務(wù)器端通過輸入輸出流進(jìn)行雙向的消息通信。
(6)當(dāng)通信完畢后,客戶端和服務(wù)器同時關(guān)閉本次連接。
由于Android應(yīng)用程序是使用Java進(jìn)行開發(fā),因此,在Android平臺下開發(fā)基于Socket的C/S模式程序非常簡單,直接使用Java中的Socket與ServerSocket類即可。這與傳統(tǒng)Java的網(wǎng)絡(luò)套接字開發(fā)幾乎沒有區(qū)別,對于熟悉Java的大部分讀者來說非常簡單。
2.5.2 服務(wù)器端
上一小節(jié)簡單介紹了基于Socket的C/S模式網(wǎng)絡(luò)程序的基本工作原理,從本小節(jié)開始將向讀者介紹一個基于Socket的簡單案例。首先介紹服務(wù)端的開發(fā),由于本案例比較簡單,所以僅有一個類Sample2_8_Server,其代碼如下。
代碼位置:見隨書中源代碼/第2章/Sample2_8_Server/src/com/bn/Sample2_8_Server目錄下的Sample2_8_Server.java。
1 package com.bn.Sample2_8_Server; //聲明包名 2 import java.io.DataInputStream; //導(dǎo)入相關(guān)類 3 ……//此處省略了部分類的引入代碼,讀者可自行查看隨書的源代碼 4 import java.net.Socket; //導(dǎo)入相關(guān)類 5 public class Sample2_8_Server{ 6 static ServerSocket sSocket; // ServerSocket的引用 7 public static void main(String[] args){ //主方法 8 try{ 9 sSocket=new ServerSocket(8877); //創(chuàng)建ServerSocket對象 10 System.out.println("監(jiān)聽8877接口……"); //打印信息 11 while(true){//服務(wù)器啟動后一直循環(huán)服務(wù)于不同的客戶端 12 Socket socket=sSocket.accept(); //創(chuàng)建Socket對象 13 DataInputStream diStream=new DataInputStream(socket. getInputStream()); 14 DataOutputStream dotStream=new DataOutputStream(socket. getOutputStream()); 15 System.out.println("客戶端信息:"+diStream.readUTF()); 16 dotStream.writeUTF("成功連接服務(wù)器端"); //寫入到輸出流中 17 diStream.close(); //關(guān)閉輸入流 18 dotStream.close(); //關(guān)閉輸出流 19 socket.close(); //關(guān)閉Socket套接字 20 } }catch(Exception e){ //捕獲并打印異常信息 21 e.printStackTrace(); 22 } } }
? 第9行創(chuàng)建了ServerSocket對象,監(jiān)聽在服務(wù)器的8877端口。
? 第11-20行為服務(wù)循環(huán),服務(wù)器一旦成功啟動監(jiān)聽在指定的端口就進(jìn)入此循環(huán),按照指定的流程服務(wù)于一個一個的客戶端。本案例中的服務(wù)流程為:首先與客戶端建立雙向數(shù)據(jù)流,然后接收客戶端的信息,最后再向客戶端返回信息。
運行本案例,其運行效果如圖2-25所示。

▲圖2-25 對8877接口進(jìn)行監(jiān)聽
2.5.3 客戶端
開發(fā)完本案例的服務(wù)器端后,接下來在本小節(jié)中將主要介紹客戶端的開發(fā)。由于本案例功能簡單,因此客戶端也僅有一個類Sample2_8_ ClientActivity,其代碼如下。
代碼位置:見隨書中源代碼/第2章/Sample2_8_Client/src/com/bn/Sample2_8_Client目錄下的Sample2_8_ClientActivity.java。
1 package com.bn.Sample2_8_Client; //聲明包名 2 ……//此處省略了部分類的引入代碼,讀者可自行查看隨書的源代碼 3 public class Sample2_8_ClientActivity extends Activity{//創(chuàng)建繼承Activity的主控制類 4 @Override 5 public void onCreate(Bundle savedInstanceState){ //重寫的onCreate方法 6 super.onCreate(savedInstanceState); 7 setContentView(R.layout.main); //跳轉(zhuǎn)到主界面 8 Button button=(Button)findViewById(R.id.button); //獲得Button按鈕的引用 9 button.setOnClickListener( //為Button按鈕添加監(jiān)聽器 10 new OnClickListener(){ 11 public void onClick(View v){ //重寫的onClick方法 12 new Thread(){ 13 public void run(){ 14 connectServer(); //調(diào)用connectServer連接服務(wù)器 15 }}.start(); 16 }} ); } 17 public void connectServer(){ //自定義的連接服務(wù)器的方法 18 String serverIp="10.16.189.20"; //聲明服務(wù)器端IP 19 try{ 20 Socket socket=new Socket(serverIp,8877); //創(chuàng)建Socket套接字,發(fā)出連接請求 21 DataInputStream din=new DataInputStream(socket.getInputStream()); 22 DataOutputStream dout=new DataOutputStream(socket.getOutputStream()); 23 EditText et=(EditText)this.findViewById(R.id.et); //獲得EditText輸入對話框?qū)ο? 24 String tempStr=et.getText().toString(); //獲取該對話框中的信息 25 dout.writeUTF(tempStr); //將信息寫入到輸出流中 26 TextView tv=(TextView)this.findViewById(R.id.tv); //獲得TextView的對象 27 tv.setText(din.readUTF()); //將輸入流中的數(shù)據(jù)在TextView中顯示 28 din.close(); //關(guān)閉輸入流 29 dout.close(); //關(guān)閉輸出流 30 socket.close(); //關(guān)閉Socket套接字 31 }catch(Exception e){ 32 e.printStackTrace(); //捕獲并打印異常信息 33 }}}
? 第5-16行為繼承Activity后重寫的onCreate方法,該方法在程序開始時執(zhí)行。在該方法中首先獲得“連接服務(wù)器端”按鈕對象的引用,之后為該按鈕添加監(jiān)聽器,監(jiān)聽器功能為connectServer方法連接服務(wù)器收發(fā)信息。
? 第17-33行為連接服務(wù)器收發(fā)信息的connectServer方法,其基本的工作流程為:首先向服務(wù)器發(fā)出連接請求,連接成功后建立雙向數(shù)據(jù)流,然后將用戶輸入的信息發(fā)送給服務(wù)器端再從服務(wù)器端接收反饋信息。
提示
在創(chuàng)建Socket套接字對象時需要指明端口號以及服務(wù)器端的IP,這里的IP必須為真實IP,不能使用環(huán)回地址“127.0.0.1”。因此運行本案例時讀者有可能需要根據(jù)自己計算機的具體情況修改服務(wù)器的IP地址,使得程序可以正常運行。同時,在開發(fā)客戶端時需要在AndroidManifest.xml中聲明聯(lián)網(wǎng)權(quán)限,具體情況參見中的源代碼。
運行本案例,在上面的文本框中輸入需要發(fā)送的信息,然后單擊“連接服務(wù)器端”按鈕。若網(wǎng)絡(luò)沒有問題,則在服務(wù)器端可以收到客戶端發(fā)送的信息,如圖2-26所示。同時,客戶端也會收到服務(wù)器的反饋信息,如圖2-27所示。

▲圖2-26 服務(wù)器端收到客戶端信息

▲圖2-27 客戶端成功連接到服務(wù)器
- 游戲劇本怎么寫
- 人本游戲
- 游戲設(shè)計的236個技巧:游戲機制、關(guān)卡設(shè)計和鏡頭竅門
- 游戲開發(fā)實戰(zhàn)寶典
- 3ds max+Photoshop游戲場景設(shè)計(第4版)
- 傳奇 奇幻插畫創(chuàng)作藝術(shù)
- 妙趣橫生的游戲制作之旅
- 實例妙解Cocos2D-X游戲開發(fā)
- Unreal Engine 4 游戲開發(fā)指南
- 傳奇 游戲角色及場景設(shè)定藝術(shù)
- 電子游戲與多元智能培養(yǎng)
- 游戲藝術(shù):從傳統(tǒng)到現(xiàn)代的發(fā)展歷程
- 精通游戲測試(第3版)
- Unity 3D虛擬現(xiàn)實游戲開發(fā)
- OGRE 3D游戲開發(fā)框架指南