熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

使用Java實現數據報通訊過程

2013-11-15 11:35:59  來源: JSP教程 

  數據報(Datagram)使網絡層數據單元在介質上傳輸信息的一種邏輯分組格式它是一種在網絡中傳播的獨立的自身包含地址信息的消息它能否到達目的地到達的時間到達時內容是否會變化不能准確知道的它的通訊雙方是不需要建立連接的對於一些不需要很高質量的應用程序來說數據報通訊是一個非常好的選擇在Java的包中有兩個類DatagramSocket和DatagramPacket為應用程序中采用數據報通訊方式進行網絡通訊
  下面我想詳細解釋在Java中實現客戶端與服務器之間數據報通訊的方法請看
  一客戶端應用程序的工作流程
  ) 首先要建立數據報通訊的Socket我們可以通過創建一個DatagramSocket對象來實現它在Java中DatagramSocket類有如下兩種構造方法
  a)public DatagramSocket() 構造一個數據報socket並使其與本地主機任一可用的端口連接若打不開socket則拋出SocketException異常
  b) public DatagramSocket(int port) 構造一個數據報socket並使其與本地主機指定的端口連接若打不開socket或socket無法與指定的端口連接則拋出SocketException異常
  ) 創建一個數據報文包用來實現無連接的包傳送服務每個數據報文包是用DatagramPacket類來創建DatagramPacket對象封裝了數據報包數據包長度目標地址目標端口作為客戶端要發送數據報文包要調用DatagramPacket類以如下形式的構造函數創建DatagramPacket對象將要發送的數據和包文目的地址信息放入對象之中
  DatagramPacket(byte bufferedarray[]int lengthInetAddress addressint port)即構造一個包長度為length的包傳送到指定主機指定端口號上的數據報文包參數length必須小於等於bufferedarrylength
  DatagramPacket類提供了四個類來獲取信息
  a) public byte[] getData() 返回一個字節數組包含收到或要發送的數據報中的數據
  b) public int getLength() 返回發送或接收到的數據的長度
  c) public InetAddress getAddress() 返回一個發送或接收此數據報包文的機器的IP地址
  d) public int getPort() 返回發送或接收數據報的遠程主機的端口號
  )創建完DatagramSocket和DatagramPacket對象就可以發送數據報文包了發送是通過調用DatagramSocket對象的send方法實現它需要以DatagramPacket對象為參數將剛才封裝進DatagramPacket對象中的數據組成數據報發出
  )當然我們也可以接收數據報文包為了接收從服務器返回的結果數據報文包我們需要創建一個新的DatagramPacket對象這就需要用到DatagramPacket的另一種構造方式DatagramPacket(byte bufferedarray[]int length)即只需指明存放接收的數據報的緩沖區和長度調用DatagramSocket對象的receive()方法來完成接收數據報的工作此時需要將上面創建的DatagramPacket對象作為參數該方法會一直阻塞知道收到一個數據報文包此時DatagramPacket的緩沖區中包含的就是接收到的數據數據報文包中也包含發送者的IP地址發送者機器上的端口號等信息
  )處理接收緩沖區內的數據獲取服務結果
  )當通訊完成後可以使用DatagramSocket對象的close()方法來關閉數據報通訊Socket當然Java自己會自動關閉Socket釋放DatagramSocket和DatagramPacket所占用的資源但是作為一種良好的編程習慣還是要顯示的予以關閉
  下面我給出一個簡單的利用數據報通訊的客戶端程序它能夠完成與服務器簡單的通訊為了直觀我把它寫成了Applet程序由於本文不是介紹Applet所以我只寫了簡要的注釋對Applet感興趣的朋友親參閱有關書籍
  
    import javaapplet*;
    import javaawt*;
    import *;
    import javaio*;
  
    public final class javaCommunicationClient extends Applet
    {
     private Label labellabel ;
     private Panel panelpanel;
     private TextField textfield;
     private TextArea textarea;
     private DatagramSocket sendSocketreceiveSocket;//聲明發送數據報Socket和接收數據報Socket
     private DatagramPacket sendPacketreceivePacket;//聲明發送數據報文包和接收數據報文包
  
    public void init()
     {
      setBackground(Colorgray);
      setLayout(new BorderLayout());//設置一個布局管理器
      panel=new Panel();
      panelsetLayout(new BorderLayout());//在容器中放置布局管理器
      label=new Label(通話紀錄);
      textarea=new TextArea();//文本顯示區域
      textareasetText(歡迎您!);
      paneladd(Northlabel);//將標簽添加到布局管理器中
      paneladd(Centertextarea);
      add(Northpanel);
      label=new Label(發言);//創建另一個容器
      paneladd(Centerlabel);
      textfield=new TextField();
      textfieldsetText();
      paneladd(Southtextfield);
      add(Centerpanel);
      show();
     }
  
    public void start()
     {
      waitForPackets();
     }
  
    public void waitForPackets()
  
    /*方法waitForPacket用來監聽來自於服務器的數據報當獲得數據報後在文本顯示區域顯示出來
  
    */
    {
     try
     {
      sendSocket=new DatagramSocket();//實例化一個發送數據報Socket對象
      receiveSocket= new DatagramSocket();//實例化一個接收數據報Socket對象為端口
  
      } catch (SocketException e)//捕獲異常
     {
      textareaappendText(不能打開數據報Socket或數據報Socket無法與指定端口連接!);
     }
     while (true)
      {
       try
       {
        byte buf[]=new byte[];
        receivePacket=new DatagramPacket(bufbuflength);//實例化一個接收數據報文包對象
  
        receiveSocketreceive(receivePacket);//以receivePacket為參數接受文包
        textareaappendText(\n服務器\t);
        byte[] data=receivePacketgetData();
        String receivedString=new String(data);
        textareaappendText(receivedString);//將接收到的數據報文報中的數據顯示出來
       } catch(IOException e)
      {
       textareaappendText(網絡通訊出現錯誤問題在+etoString());
      }
     }
    }
  
    public boolean action(Event eObject o)
     {
      try
       {textareaappendText(\n客戶端);
       String string=otoString();
       textareaappendText(string);
       byte[] databyte=new byte[];
       stringgetBytes(stringlength()databyte);
       sendPacket=new DatagramPacket(databytestringlength()InetAddressgetByName());//發送數據報其中你可以用你自己的主機IP替換器中的IP地址
       sendSocketsend(sendPacket);
      }catch(IOException ioe)
      {
       textareaappendText(網絡通訊出現錯誤問題在+ioetoString());
      }
     return true;
    }
  
    }
  二服務器端應用程序的工作流程
  
    不同於基於數據流通訊方式在數據報通訊中通訊雙方之間並不要建立連接所以服務器應用程序通訊過程與客戶端應用程序的通訊過程使非常相似的也要建立數據報通訊DatagramSocket構建數據報文包DatagramPacket接收數據報和發送數據報處理接收緩沖區內的數據通訊完畢後關閉數據報通訊Socket不同的是服務器應用程序要面向網絡中的所有計算機所以服務器應用程序收到一個包文後要分析它得到數據報的源地址信息這樣才能創建正確的返回結果報文給客戶機
  
    下面我給出了一個數據報通訊的服務器段程序由於服務器端的相應應用程序和客戶端程序比較相似所以我不想詳細的注釋僅列出程序供大家參考
  
    javaCommunicationServerjava
  
    import *;
    import javaio*;
    import javaawt*;
    import javaappletApplet;
  
    public final class javaCommunicationServer extends Frame
     {
      private Label labellabel ;
      private Panel panelpanel;
      private TextField textfield;
      private String namename;
      private TextArea textarea;
      private DatagramSocket sendSocketreceiveSocket;
      private DatagramPacket sendPacketreceivePacket;
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19271.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.