The NoteBook of EricKong

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

          建立連接
          既然是通信,當然第一步就是要建立連接啦。我們還是用最簡單的看代碼的方式來開始我們的連接。

          ==========================================
          ==服務端代碼:Jserver1.java
          ==========================================

          import java.net.*;
          import java.io.*;
          public class Jserver1 {
          public static void main(String[] args) {
          ServerSocket server=null;
          try{
             server=new ServerSocket(719);//在端口719建立一個服務器套接字對象
            System.out.println("服務端等待");
            while(true){
             System.out.println("等待客戶機");
             Socket newSocket=server.accept();//客戶端向我們建立的服務器套接字發送連接請求,則向下執行
             System.out.println("已與客戶機連接");
            }
          }catch(IOException ie)
          {
            System.out.println(ie);
          }finally{
            try
            {
             if(server!=null) server.close();//關閉服務器套接字。為什么要用finally關鍵字來做這個事呢?HOHO thinking in java里大師已經說得很清楚了,就是無論出現什么異常,都保證我們的服務端套接字能被關閉。
            }catch(IOException ie){}
          }
          }
           嘎嘎,怎么樣 注釋寫得夠清楚了吧?OK 讓我們編譯運行,得到的結果應該如圖:

          OK 再讓我們來看看客戶端的代碼是怎么樣的:
          ==========================================
          ==客戶端代碼:Jclient1.mxml
          ===================================================


          <?xml version="1.0" encoding="utf-8"?>
          <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creati f width="349" height="326">
          <mx:Script>
            <![CDATA[
            import flash.net.Socket;
            private var socket:Socket;
            internal function initApp():void
            {
             socket=new Socket();//創建Socket對象
             socket.connect("localhost",719);  //連接服務器
             socket.addEventListener(Event.CONNECT,connectFun);//監聽是否連接上服務器
             socket.addEventListener(Event.CLOSE,closeFun);//監聽套接字連接是否關閉
            }
            private function connectFun(event:Event):void
            {
             jText.text+="已經成功連接到服務器!\n";
            }

            private function closeFun(event:Event):void
            {
             jText.text+="和服務器斷開!\n"
            }
            ]]>
          </mx:Script>
          <mx:TextArea x="10" y="10" width="327" height="309" id="jText"/>
          </mx:Application>

          界面非常簡單啦,其實就是一個TextArea來顯示連接的結果而已,運行的結果如下圖(注意,服務端也應該在運行!):

          在as3.0中,所有和網絡通信有關的類都位于flash.net包中,這里使用的是Socket類對象。
          ==========================================
          ==我們來詳細說明一下上面用到的Socket類:
          ==========================================

          Socket對象的常用創建方法有下面2種:
          var socket:Socket=new Socket();//例一
          或者
          var socket:Socket=new Socket("localhost",719);//例二.這條語句設置了服務器地址為localhost 端口是719

          當指定了了服務器地址和端口,Socket對象將自動開始連接服務器。如果不指定,則需要條用connect方法才開始執行連接動作,意思就是,例二的代碼和下面的代碼是等效的:

          var socket:Socket=new Socket();
          socket.connect("localhost",719);
          完成連接動作后,接下來要獲取服務端得返回信息。
          Socket對象和URLLOADER啊之類的對象都是一樣,利用事件機制來處理服務器端的信息,我們只要給Socket對象添加相關的事件監聽函數就可以捕捉到服務器端的信息,Socket對象的事件主要有:
          1 Event.CLOSE 連接中斷事件。
          2 Event.CONNECT 連接狀態事件,表示已經成功連接了服務器。
          3 IOErrorEvent.IO_ERROR 信息傳遞錯誤事件,一般是由服務器地址錯誤引起的。
          4 ProgressEvent.SOCKET_DATA 服務器信息事件,當收到服務器的新信息時被觸發。

          ==========================================

          哈哈,經過上面的代碼,我們的服務端MM和客戶端GG終于通過Socket這個緣分宿命的相遇了!接下來會發生什么?我們繼續往下看~~
          三、第一封情書(客戶端發送消息,服務端接受消息)

           

          客戶端GG在遇到服務端MM以后,終日變得茶飯不思,在折磨掉了無數根頭發以后,客戶端GG終于下定決心,要向服務端MM送出第一封情書啦!

          既然是客戶端GG送出情書,那我們先來看他到底是怎么做的:
          ==========================================
          ==客戶端代碼:Jclient2.mxml
          ==========================================

          <?xml version="1.0" encoding="utf-8"?>
          <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12" creationComplete="initApp()">
          <mx:Script>
          <![CDATA[
          import flash.net.Socket;
          import flash.utils.ByteArray;

          private var socket:Socket=new Socket(); //定義Socket,準備好情書的信封
          //初始化程序
          internal function initApp():void
          {
          socket.connect("localhost",719); //連接服務器
          socket.addEventListener(Event.CONNECT,funConnect); //監聽是否連接
          socket.addEventListener(Event.CLOSE,funClose); //監聽連接關閉
          }
          internal function funConnect(event:Event):void
          {
          myText.text+="連接已建立 \n";
          }
          internal function funClose(event:Event):void
          {
          myText.text+="連接已關閉 \n";
          }

          internal function sendMessage(msg:String):void//發送數據對應按鈕click事件
          {
          var message:ByteArray=new ByteArray();//新建一個ByteArray存放數據
          message.writeUTFBytes(msg +"\r\n");//寫入數據,writeUTFBytes方法,以utf-8格式傳數據避免中文亂碼
          socket.writeBytes(message);  //寫入Socket的緩沖區
          socket.flush();  //調用flush方法發送信息
          myText.text+=msg+"\r\n";  //在客戶端屏幕上輸出發送的內容
          myInput.text=""; //清空發言框
          }
          ]]>
          </mx:Script>
          <mx:TextArea x="10" y="10" width="703" height="263" id="loveText"/>
          <mx:TextInput x="10" y="297" width="605" id="loveInput"/>
          <mx:Button x="648" y="297" label="發送情書" id="sendBtn" click="sendMessage(loveInput.text)"/>
          </mx:Application>

          嘎嘎,情書的做法就上面那面簡單,注釋已經寫得很清楚了,就不多說了。

          OK,客戶端GG的情書倒是送出去了,我們就來看看服務端MM是怎么接受這封情書的呢?


          OK,客戶端GG的情書倒是送出去了,我們就來看看服務端MM是怎么接受這封情書的呢?
          ==========================================
          ==服務端代碼:Jserver2.java
          ==========================================

          import java.net.*;
          import java.io.*;
          public class Jserver2{
          private BufferedReader reader; //負責輸入
          private ServerSocket server;   //服務器套接字
          private Socket socket;      //套接字
          public Server2(){}  //缺省構造函數
          void startServer()  //啟動服務器
          {
          try
          {
          server=new ServerSocket(719);    //創建服務器套接字
          System.out.println("服務器套接字建立完畢");
          while(true)
          {
            System.out.println("等待客戶端GG");
            socket=server.accept(); //若客戶端GG提出連接請求,與socket連接
            System.out.println("完成與客戶端的連接");
          reader=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8")); //獲取socket輸入流,“utf-8”這個編碼設置是為了更好顯示中文
          getMessage();//讀取來自客戶端的數據,并輸出至畫面上
          }
          }catch(Exception e)
          {
          System.out.println(e);
          }finally{
          try
          {
          if(server!=null) server.close();//關閉服務器套接字。
          }catch(IOException ie){}
          }
          }
          void getMessage()  //讀取來自套接字的信息
          {
          try
          {
          while(true)    //循環
          {
          System.out.println("客戶端GG說:"+reader.readLine());
          }
          }catch(Exception e){}
          finally{
          System.out.println("客戶端中斷連接");
          try
          {
          if(reader!=null) reader.close(); //關閉套接字的輸入流
          if(socket!=null) socket.close();  //關閉套接字
          reader=null;
          socket=null;
          }catch(Exception e){}
          }
          }
          public static void main(String[] args)
          {
          Server2 server=new Server2();
          server.startServer();
          }

          }

          哈哈,我們運行來看看,我們的客戶端GG的情書能否順利到達服務端MM的手中呢?
          運行結果如下:


          HOHO 看樣子我們的客戶端GG的情書,服務端MM是順利接受到啦。

           

          四、服務端MM的心思(多客戶端通信)


          在服務端MM收到客戶端GG的情書以后,突然發現自己原來還是蠻受歡迎的呢。但是有句俗話說的好,那就是“不能為了一棵樹放棄一片森林”。所以服務端MM就想,能不能多接受幾個客戶端GG的情書呢?(真TMD賤。。。)

          OK,既然服務端MM有了這個需求(雖然是很賤的需求),那我們就要來滿足她!

          來看服務端的代碼:
          =========================================
          ==Jserver3.java
          =========================================

           

          import java.net.*;
          import java.io.*;
          import java.util.*;

          public class Jserver3 {
          private ServerSocket server;
          List sManager = new ArrayList();

          public Jserver3(){}
          void startServer() //運行服務器
          {
          try
          {
          server=new ServerSocket(719);
          System.out.println("服務器套接字已創建成功!");
          while(true)
          {
          Socket socket=server.accept();
          System.out.println("已經與客戶端連接");
          new J_Thread(socket).start();
          sManager.add(socket);
          System.out.println("當前客戶端連結數:"+sManager.size());
          }
          }catch(Exception e){}finally
          {
          try
          {
          server.close();
          }catch(Exception e){}
          }
          }
          public static void main(String[] args) {

          Jserver3 server=new Jserver3();
          server.startServer();
          }
          class J_Thread extends Thread  //與客戶端進行通信的線程類
          {
          Socket socket;   //套接字引用變量
          private DataInputStream reader;   //套接字輸入流
          private DataOutputStream writer;  //套接字輸出流
          J_Thread(Socket socket)   //構造函數
          {
          this.socket=socket;
          }
          public void run()
          {
          try
          {

          reader=new DataInputStream(socket.getInputStream());//獲取套接字的輸入流
          writer=new DataOutputStream(socket.getOutputStream());//獲取套接字的輸出流
          String msg;
          while((msg=reader.readUTF())!=null)//如果收到客戶端發來的數據
          {
          //向客戶端發送信息
          writer.writeUTF("您的情書已經收到");
          writer.flush();
          System.out.println("來自客戶端:"+msg);

          }
          }catch(Exception e){}finally
          {
          try
          {
          sManager.remove(socket);  //刪除套接字
          //關閉輸入輸出流及套接字
          if(reader!=null)reader.close();
          if(writer!=null)writer.close();
          if(socket!=null)socket.close();
          reader=null;
          writer=null;
          socket=null;

          System.out.println("客戶端離開");//向屏幕輸出相關信息
          System.out.println("當前客戶端的連接數:"+sManager.size());
          }catch(Exception e){}
          }
          }
          }

          }

          嘎嘎 在這段代碼里,服務端MM為每一個連接的客戶端GG分配一個單獨的線程,而每一個線程里都持有對應的客戶端GG的Socket對象。SO,通過這些多線程,服務端MM就練就了一心N用的功力,可以同時接受N個客戶端GG發來的情書了( ,真的太賤了。。。。)

          客戶端的代碼和上面的客戶端代碼一模一樣的,這里就不多說啦!

           


          好了,在這里就簡單的給大家介紹了如何實現java和flash(flex)實現socket通信的簡單功能。有時間的話,再給大家來個簡單的聊天室實現(那個時候的服務端MM就更賤了,不僅收著N多客戶端GG的情書,竟然還把情書廣播給所有的客戶端GG,BS!)。嘎嘎 其實原理就是上面所說的這些,大家自己都可以嘗試下。

          posted on 2010-09-19 12:33 Eric_jiang 閱讀(1970) 評論(1)  編輯  收藏 所屬分類: Socket

          Feedback

          # re: flex與JAVA的SOCKET通信[未登錄] 2013-08-24 23:15 liu
          為什么多線程,不行,這段好像不執行
          while((msg=reader.readUTF())!=null)//如果收到客戶端發來的數據
          {
          //向客戶端發送信息
          writer.writeUTF("您的情書已經收到");
          writer.flush();
          System.out.println("來自客戶端:"+msg);

          },  回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 连江县| 手机| 长丰县| 嘉黎县| 石城县| 孟村| 玉溪市| 荃湾区| 含山县| 张家港市| 临泽县| 承德县| 石林| 融水| 塘沽区| 出国| 会宁县| 深水埗区| 嘉义市| 富蕴县| 且末县| 上林县| 庆元县| 遵化市| 纳雍县| 漳浦县| 宕昌县| 丰城市| 越西县| 塔河县| 华容县| 旬邑县| 仁寿县| 清水县| 永和县| 河南省| 鄢陵县| 炉霍县| 修文县| 祁东县| 大冶市|