一個基於UDP資料廣播的區域網路會議程式

weixin_34262482發表於2011-10-21
蔣清野 (qjiang@ieee.org)美國導航與控制公司

簡介: 本文介紹了網路通訊中通用的傳輸控制協議(TCP)和使用者資料包協議(UDP),並 且利用Java語言設計了一個簡單的基於UDP 資料廣播的區域網路會議程式,展示了 在Java語言中進行UDP 資料傳送和接收的一般步驟。由於Java語言卓越的跨平臺特 性,本系統能夠不加修改的執行在Windows, Linux, Mac OS等一系列不同平臺上。

介紹

隨著網路技術的普及,網路會議在公司、企業和單位中的應用也越來越廣。一 個網路會議系統通常包括一個伺服器程式和一個客戶端程式。其中伺服器端負責進 行使用者管理、資訊互動以及表決統計;客戶端則實現收聽發言,公開發言,私下討 論、投票表決等功能。在一個網路會議系統的設計和實現中,通常涉及到圖形使用者 介面設計,TCP/IP連線,UDP 資料廣播,多執行緒等一系列技術。本文通過一個簡單 示例程式,展示了在Java語言中進行UDP 資料傳送和接收的一般步驟以及UDP 資料 廣播在區域網路會議系統中的作用。

TCP (Transmission Control Protocol,傳輸控制協議) 是一種基於連線的通 訊協議。當兩臺計算機之間需要進行可靠的資料傳輸時,它們通過網路建立起一個 穩定的連線,這種連線通常也被稱為資料鏈。與電話網路相類似,這種資料鏈是點 對點的,通訊的雙方則通過這條資料鏈來回傳輸資料。在這條穩定的資料鏈的基礎 上,TCP 協議通過資訊校驗能夠保證接收方所接收到的資料和傳送方所傳送的資料 在內容和順序上是完全一致的,從而實現了資料的可靠傳輸。

UDP (User Datagram Protocol,使用者資料包協議)與TCP 協議之間的不同在於 UDP 不是一種基於穩定連線的通訊協議。UDP 協議將獨立的資料包從一臺計算機傳 輸到另外一臺計算機,但是並不保證接受方能夠接收到該資料包,也不保證接收方 所接收到的資料和傳送方所傳送的資料在內容和順序上是完全一致的。因此,UDP 協議更類似於普通郵政服務,寄信人不能夠保證所寄出去的信能夠被收信人及時收 到,後發出的信也許會比先發出的信更早到達。

對於很多應用程式來說,在互相通訊的兩臺計算機之間保證一個可靠與穩定的 資料鏈是至關重要的。在這種情況下,就應該首先考慮使用TCP 協議在涼臺計算機 之間建立起TCP/IP連線。在HTTP (Hyper-Text Transfer Protocol,超級文字傳輸 協議)、FTP (File Transfer Protocol, 檔案傳輸協議)以及TELNET 應用程式中, 均要求在通訊的雙方之間建立起穩定可靠的資料鏈,因此它們都使用了TCP 協議來 進行資料傳輸。

在TCP 協議中,傳送方和接收方必須交換額外的資訊以保證接收方已經接收到 所傳送的資料包並且所接收到的資料和傳送方所傳送的資料在內容和順序上是完全 一致的。這些額外的資訊交換提高了資料傳輸的可靠度,但是也給網路帶來了額外 的負擔,導致資料交換的延遲,從而降低了整個網路的資料交換能力。對於某些對 實時性要求較高的應用程式來說,這樣的延遲有可能是不可接受的。例如一個毫秒 級的時鐘伺服器按照一定的頻率向客戶機提供當時的時間資料,如果這些時間資料 在傳輸過程中受到了較大的延遲,這些過時的時間資料是完全沒有意義的,即使客 戶機準確無誤的接收到了這些資料。相反,如果客戶機所接收到的每一個資料包都 是實時的,那麼即使客戶機錯過了一兩個資料包也是可以接受的,因為他總是可以 根據後面所接收到的資料包來對自己進行校正。因此,對於對實時性要求比較高但 是對傳輸可靠度要求比較低的應用程式來說,UDP 協議顯然是一個合適的選擇。

在通用的乙太網(Ehternet)構架下,計算機於計算機之間的資料交換都是通過 交換機來完成的。如果一份資料需要被傳送給多個接收者,在使用TCP/IP連線的情 況下,資料傳送者需要向交換機傳送N 個同樣的拷貝,而交換機則負責將這N 個拷 貝分發給所有的接收者;在使用UDP 資料廣播的情況下,資料傳送者只需要向交換 機傳送一個拷貝,交換機負責將這個資訊製作N 個拷貝傳送給所有的機器。在這種 情況下,使用TCP/IP連線會大大的增加網路的負擔。在一個普通區域網路中,可以 認為由於網路狀況較差而造成資料丟失的可能性比較小,而利用UDP 資料廣播進行 資料交換能夠大幅度減輕網路的負擔,因此設計一個基於UDP 資料廣播的區域網路 會議系統式完全可行的。

通常來說,一臺計算機只有一個物理介面與網路相連線,所有的應用程式均通 過該物理介面從網路接收資料或者將資料傳送到網路。由於一個網路上同時存在多 臺計算機,並且一臺計算機上有可能同時存在多個應用程式需要與網路進行資料交 換,我們通常使用IP和埠號來識別需要進行資料交換的計算機和應用程式。每臺 計算機由一個32位的IP地址來識別,在一個網路中,每臺計算機的IP地址都是唯一 的,因此應用程式能夠根據IP地址來將資料傳送到正確的計算機。每個需要與網路 進行資料交換的應用程式均被系統分配一個16位的埠號,系統根據這個埠號將 從網路接收到的資料轉發給相對應的應用程式。埠號的範圍是從0 到65535 ,其 中從0 到1023被系統所保留,主要是用來提供HTTP, FTP 以及TELNET等系統服務, 因此使用者自己的應用程式不應該試圖去使用小於1023的埠。

Java語言的一個顯著優點就是它從語言的高度上提供了對網路的支援,使得程 序員能夠很容易的構建基於網路的應用程式。在Java 1.3版的標準類庫java.net中 提供了5 個介面以及21個Java類,在這些介面和類的基礎上,程式設計師能夠輕易的實 現幾乎是所有的常見網路應用。例如,ServerSocket能夠用來構建基於TCP/IP的服 務器程式,Socket能夠用來構建基於TCP/IP的客戶端程式,而DatagramPacket以及 DatagramSocket能夠用來構建基於UDP 的資料廣播程式。在java.net中的其他Java 庫能夠被用來實現域名解析、身份認證、安全許可等一系列功能。由於這些Java庫 的功能和具體用法等內容已經超出了本文的討論範圍,感興趣的讀者可以進一步參 考Java的文件以及Sun 公司的Java Tutorial等資料。

這個簡單的程式包括如下三個模組:

  1. 資料廣播與接收模組-- Broadcast.java
  2. 資料接收執行緒 -- Receiver.java
  3. 圖形使用者介面 -- Chat.java

程式設計

資料廣播與接收模組Broadcast.java是本示例程式的核心部分。該類包括一個 構造方法,一個資料傳送方法和一個資料接收方法。為了使這個類能夠被更加廣泛 的應用到其它應用程式中,作者又新增了一個埠配置方法。

在構造方法中,我們首先利用InetAddress 定義一個資料廣播組,同時構造一 個用於傳送資料的DatagramSocket與一個用於接收資料的MulticastSocket。 在這 裡我們使用230.0.0.1 來作為資料廣播組的標示符,雖然這個標示符與IP地址的格 式相同,但是它並不表示Internet上的一臺機器。此外,我們在埠配置方法中分 別指定1235埠和1236埠位資料傳送和資料接收埠。如果把一個UDP 資料廣播 系統比喻成無線電廣播系統的話,資料廣播標示符可以被認為是波段,而資料接收 埠可以被認為是頻率。收音機使用者必須把收音機調整到相應的波段和頻率才能夠 接收到電臺訊號,我們的UDP 資料接收程式也必須加入相對應的資料廣播組並且使 用正確的資料接收埠才能夠正確的接收到UDP 廣播資料。在構造方法中,我們利 用MulticastSocket 的建構函式指定資料接收埠(頻率),並利用其joinGroup 方 法指定資料廣播組(波段)。

public Broadcast()
    {
        GetBroadcastPorts();
        try
        {
                // 構造資料廣播組標示符 (波段)
            BroadcastGroup = InetAddress.getByName("230.0.0.1");
                // 構造資料傳送埠
            Sender         = new DatagramSocket(ServerPort);
                // 構造資料接收埠 (頻率)
            Receiver       = new MulticastSocket(ClientPort);
                // 指定資料接收埠的資料廣播組 (波段)
            Receiver.joinGroup(BroadcastGroup);
        } catch (Exception e) {}
    }

在資料傳送方法中,我們基於使用者所提供的資料以及資料廣播目標埠(頻率) 構造一個DatagramPacket資料包,然後利用傳送資料的DatagramSocket的send方法 將該資料包傳送到區域網。與此相反,在資料接收方法中,我們首先構造一個空的 DatagramPacket資料包,然後利用接收資料的MulticastSocket的receive方法填充 該資料包中的內容。為了避免由於資料包大小不同所造成的資料丟失等麻煩,我們 特地將兩個資料包的大小設定成一樣的。

   // 資料傳送方法
    public void SendData(String Msg)
    {
        byte[] b = new byte[1024];
        DatagramPacket packet;
        try
        {
            // 位元組序列b 包括需要傳送的資料
            b = Msg.getBytes();
            // 構造一個資料包,BroadcastGroup是資料廣播組標示符(波段),
            // ClientPort是資料廣播目標埠(頻率)。
            packet = new DatagramPacket(b, b.length, BroadcastGroup, ClientPort);
            // 傳送資料包
            Sender.send(packet);
        } catch (Exception e) {}
    }
    
    // 資料接收方法
    public String ReceiveData()
    {
        byte[] b = new byte[1024];
        // 構造一個空的資料包
        DatagramPacket packet = new DatagramPacket(b, 1024);
        String InMsg;           
        try
        {
                // 接收資料
            Receiver.receive(packet);
    } catch (IOException e) {}
    // 叢資料包中獲得接收到的資料
        b = packet.getData();
        InMsg = new String(b);
    return InMsg;   
    }

資料接收執行緒Receiver.java的任務是接收廣播資料並更新圖形使用者介面。該類 的建構函式包括兩個引數,引數listener指定用來接收資料的Broadcast物件,引數 display則指定用來顯示會議內容的TextArea物件。在其執行方法run 中,迴圈呼叫 Broadcast物件的資料接收方法ReceiveData 接收廣播資料,並且利用TextArea物件 的append方法將新接收到的內容顯示到圖形使用者介面上。

public class Receiver extends Thread
{
    Broadcast Listener;
    TextArea  Display;
    String    InMsg;
    
        // 構造方法
    public Receiver(Broadcast listener, TextArea display )
    {
                // Listener 是一個資料傳送與接收物件,用來接收資料。
        Listener = listener;
                / Display是一個TextArea物件,用來顯示會議內容。
        Display  = display;
    }
    
        // 執行方法
    public void run()
    {
        while(true)
        {
                        // 接收廣播資料
            InMsg = Listener.ReceiveData();
                        // 更新圖形使用者介面
            Display.append(InMsg);
            Display.append("\n");
        }
    }
}

圖形使用者介面chat.java是基於Java抽象視窗工具包AWT構建的。該介面包括一個 用來顯示會議內容TextArea,一個用來接收使用者輸入的TextField ,以及一個資料發 送命令按鈕。在Chat的構造方法中,我們首先建立圖形介面,構造一個資料傳送與接 收物件和一個資料接收執行緒,然後啟動該執行緒開始接收會議資訊。在這個方法中,我 們還利用InetAddress.getLocalHost()方法來獲得使用者的機器名,這個標示符被用來 作為使用者在網路會議中的使用者名稱。

   // 構造方法
    public Chat()
    {
        // 建立圖形介面
            add(CreateGui());
                // ....
        // 其它操作
        // ....
            // 構造一個資料傳送與接收物件
            Device = new Broadcast();
        // 構造一個資料接收執行緒
            Receiver Recv = new Receiver(Device, InMsg);
            Recv.start();
    }

程式測試

利用JDK 1.3編譯以上所有原始碼: 
javac *.java

啟動網路會議程式: 
java Chat

本示例程式在一個包括Windows 98,Windows 2000,Red Hat Linux 6.1/7.0,Mac OS,Sun Solaris等多種作業系統的區域網路中通過測試。

結論

本文介紹了網路通訊中通用的傳輸控制協議(TCP)和使用者資料包協議(UDP),並且利用Java語言設計了一個簡單的基於UDP 資料廣播的區域網路會議程式,展示了在Java語言中進行UDP 資料傳送和接收的一般步驟。本示例程式說明利用UDP 資料廣播能夠輕易實現區域網路會議的一般功能。由於Java語言卓越的跨平臺特性,一個基於Java的區域網路會議系統夠不加修改的執行在一系列不同平臺上。

關於作者

蔣清野,軟體工程專家。1999年7月獲得清華大學學士學位,2001年1月獲得伊裡諾大學(Univ. of Illinois at Urbana-Champaign)碩士學位,目前是美國導航與控制公司(American GNC Corporation)工程專家。主要研究領域包括遙感影像資訊處理,GPS應用,慣性導航,無線通訊和高速網路技術。電子郵件: qjiang@ieee.org

相關文章