本文介紹了網絡通訊中通用的傳輸控制協議(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和端口號來識別需要進行數據交換的計算機和應用程序
每台 計算機由一個
位的IP地址來識別
在一個網絡中
每台計算機的IP地址都是唯一 的
因此應用程序能夠根據IP地址來將數據發送到正確的計算機
每個需要與網絡 進行數據交換的應用程序均被系統分配一個
位的端口號
系統根據這個端口號將 從網絡接收到的數據轉發給相對應的應用程序
端口號的范圍是從
到
其 中從
到
被系統所保留
主要是用來提供HTTP
FTP 以及TELNET等系統服務
因此用戶自己的應用程序不應該試圖去使用小於
的端口
Java語言的一個顯著優點就是它從語言的高度上提供了對網絡的支持
使得程 序員能夠很容易的構建基於網絡的應用程序
在Java
版的標准類庫中 提供了
個接口以及
個Java類
在這些接口和類的基礎上
程序員能夠輕易的實 現幾乎是所有的常見網絡應用
例如
ServerSocket能夠用來構建基於TCP/IP的服 務器程序
Socket能夠用來構建基於TCP/IP的客戶端程序
而DatagramPacket以及 DatagramSocket能夠用來構建基於UDP 的數據廣播程序
在中的其他Java 庫能夠被用來實現域名解析
身份認證
安全許可等一系列功能
由於這些Java庫 的功能和具體用法等內容已經超出了本文的討論范圍
感興趣的讀者可以進一步參 考Java的文檔以及Sun 公司的Java Tutorial等資料
這個簡單的程序包括如下三個模塊
數據廣播與接收模塊
Broadcast
java
數據接收線程
Receiver
java
圖形用戶界面
Chat
java
程序設計 數據廣播與接收模塊Broadcast
java是本示例程序的核心部分
該類包括一個 構造方法
一個數據發送方法和一個數據接收方法
為了使這個類能夠被更加廣泛 的應用到其它應用程序中
作者又添加了一個端口配置方法
在構造方法中
我們首先利用InetAddress 定義一個數據廣播組
同時構造一 個用於發送數據的DatagramSocket與一個用於接收數據的MulticastSocket
在這 裡我們使用
來作為數據廣播組的標示符
雖然這個標示符與IP地址的格 式相同
但是它並不表示Internet上的一台機器
此外
我們在端口配置方法中分 別指定
端口和
端口位數據發送和數據接收端口
如果把一個UDP 數據廣播 系統比喻成無線電廣播系統的話
數據廣播標示符可以被認為是波段
而數據接收 端口可以被認為是頻率
收音機用戶必須把收音機調整到相應的波段和頻率才能夠 接收到電台信號
我們的UDP 數據接收程序也必須加入相對應的數據廣播組並且使 用正確的數據接收端口才能夠正確的接收到UDP 廣播數據
在構造方法中
我們利 用MulticastSocket 的構造函數指定數據接收端口(頻率)
並利用其joinGroup 方 法指定數據廣播組(波段)
public Broadcast()
{
GetBroadcastPorts();
try
{
// 構造數據廣播組標示符 (波段)
BroadcastGroup = InetAddress
getByName(
);
// 構造數據發送端口
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[
];
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[
];
// 構造一個空的數據包
DatagramPacket packet = new DatagramPacket(b
);
String InMsg;
try
{
// 接收數據
Receiver
receive(packet);
} catch (IOException e) {}
// 叢數據包中獲得接收到的數據
b = packet
getData();
InMsg = new String(b);
return InMsg;
}
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26516.html