官术网_书友最值得收藏!

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ù)器

主站蜘蛛池模板: 高淳县| 阳春市| 三门峡市| 阳东县| 太谷县| 揭阳市| 陇南市| 连山| 泽普县| 仁布县| 平山县| 兴安盟| 建平县| 确山县| 彭山县| 小金县| 威信县| 宕昌县| 班戈县| 鹿泉市| 屯留县| 德钦县| 堆龙德庆县| 丰原市| 阿瓦提县| 石景山区| 綦江县| 崇明县| 伊吾县| 兴山县| 常州市| 长宁区| 柯坪县| 东阳市| 沁水县| 全椒县| 台江县| 高安市| 五家渠市| 方山县| 垫江县|