一、通信方式分類
在當前的網絡通信中有三種通信模式:單播、廣播和多播(組播),其中多播出現時間最晚,同時具備單播和廣播的優點。
- 單播:單台主機與單台主機之間的通信
- 廣播:當台主機與網絡中的所有主機通信
- 多播:當台主機與選定的一組主機的通信
二、單播
單播是網絡通信中最常見的,網絡節點之間的通信 就好像是人們之間的對話一樣。如果一個人對另外一個人說話,
那么用網絡技術的術語來描述就是“單播”,此時信息的接收和傳遞只在兩個節點之間進行。
1. 單播的優點:
(1)服務器以及響應客戶端的請求;
(2)服務器能針對每個客戶端的不同請求發送不同的響應,容易顯示個性化服務;
2. 單播的缺點:
服務器針對每個客戶機發送數據流,服務器流量=客戶機數量×客戶機流量;在客戶數量大、每個客戶機流量大的流媒體應用中服務器不堪重負;
3. 應用場景:
單播在網絡中得到了廣泛的應用,網絡上絕大部分的數據都 是以單播的形式傳輸的。例如:收發電子郵件、游覽網頁時,必須與郵件服務器、網站服務器建立連接,此時使用的就是單播通信方式;
三、廣播
“廣播”可以比方為:一個人通過廣播喇叭對在場的全體說話(他才不管你是否樂意聽)。換句話說: 廣播是一台主機對某一個網絡上的所有主機發送數據報包。這個網絡可能是網絡,也可能是子網,還有可能是所有子網。
廣播有兩類:本地廣播和定向廣播
- 定向廣播:將數據報包發送到本網絡之外的特定網絡的所有主機,然而,由於互聯網上的大部分路由器都不轉發定向廣播消息,所以這里不深入介紹了
- 本地廣播:將數據報包發送到本地網絡的所有主機,IPv4的本地廣播地址為“255.255.255.255”,路由器不會轉發此廣播;
1.廣播的優點:
(1)通信的效率高,信息一下子就可以傳遞到某一個網絡上的所有主機。
(2)由於服務器不用向每個客戶端單獨發送數據,所以服務器流量比較負載低;
2.廣播的缺點:
(1)非常占用網絡的帶寬;
(2)缺乏針對性,也不管主機是否真的需要接收該數據, 就強制的接收數據;
3.應用場景:
(1)有線電視就是典型的廣播型網絡
Java廣播示例:
客戶端發送程序
//發送端程序 public class BroadcastTest { public static void main(String[] args) { //廣播的實現 :由客戶端發出廣播,服務器端接收 String host = "255.255.255.255";//廣播地址 int port = 9999;//廣播的目的端口 String message = "test";//用於發送的字符串 try { InetAddress adds = InetAddress.getByName(host); DatagramSocket ds = new DatagramSocket(); DatagramPacket dp = new DatagramPacket(message.getBytes(),message.length(), adds, port); ds.send(dp); ds.close(); } catch (Exception e) { e.printStackTrace(); } } }
服務器端接收程序
//服務器端接收程序 public class BroadcastServer { public static void main(String[] args) { int port = 9999;//開啟監聽的端口 DatagramSocket ds = null; DatagramPacket dp = null; byte[] buf = new byte[1024];//存儲發來的消息 StringBuffer sbuf = new StringBuffer(); try { //綁定端口的 ds = new DatagramSocket(port); dp = new DatagramPacket(buf, buf.length); System.out.println("監聽廣播端口打開:"); ds.receive(dp); ds.close(); int i; for(i=0;i<1024;i++) { if(buf[i] == 0) { break; } sbuf.append((char) buf[i]); } System.out.println("收到廣播消息:" + sbuf.toString()); } catch (Exception e) { e.printStackTrace(); } } }
四、多播(組播)
”組播“可以比方為:你對着大街喊:”是男人的來一下,一人發一百塊”,那么男的過來,女就不會過來,因為沒有錢發她不理你(組播:其中所有的男生就是一個組),換句話說: 組播是一台主機向指定的一組主機發送數據報包,因為如果采用單播方式,逐個節點傳輸,有多少個目標節點,就會有多少次傳送過程,這種方式顯然效率極低,是不可取的;如果采用不區分目標、全部發送的廣播方式,雖然一次可以傳送完數據,但是顯然達不到區分特定數據接收對象的目的,又會占用網絡帶寬。采用組播方式,既可以實現一次傳送所
有目標節點的數據,也可以達到只對特定對象傳送數據的目的。
IP網絡的組播一般通過組播IP地址來實現。組播IP地址就是D類IP地址,即224.0.0.0至239.255.255.255之間的IP地址。
1.組播的優點:
(1)具備廣播所具備的所有優點;
(2)與單播相比,提供了發送數據報包的效率,與廣播相比,減少了網絡流量;
2.組播的缺點:
(1)與單播協議相比沒有糾錯機制,發生丟包錯包后難以彌補,但可以通過一定的容錯機制和QOS加以彌補;
組播的簡單示例:
客戶端發送消息
//發送端程序 public class SendUdp { public static void main(String[] args) throws IOException { MulticastSocket ms=null; DatagramPacket dataPacket = null; ms = new MulticastSocket(); ms.setTimeToLive(32); //將本機的IP(這里可以寫動態獲取的IP)地址放到數據包里,其實server端接收到數據包后也能獲取到發包方的IP的 byte[] data = "組播 測試".getBytes(); InetAddress address = InetAddress.getByName("239.0.0.255"); dataPacket = new DatagramPacket(data, data.length, address,8899); ms.send(dataPacket); ms.close(); } }
服務器端接收程序:
//服務器端程序 public class TestMain { private static MulticastSocket ds; static String multicastHost="239.0.0.255"; static InetAddress receiveAddress; public static void main(String[] args) throws IOException { ds = new MulticastSocket(8899); receiveAddress=InetAddress.getByName(multicastHost); ds.joinGroup(receiveAddress); new Thread(new udpRunnable(ds)).start(); } } class udpRunnable implements Runnable { MulticastSocket ds; public udpRunnable(MulticastSocket ds) { this.ds=ds; } public void run() { byte buf[] = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, 1024); while (true) { try { ds.receive(dp); System.out.println("receive client message : "+new String(buf, 0, dp.getLength())); } catch (Exception e) { e.printStackTrace(); } } } }
運行結果截圖: