WIFI項目--【Java TCP/IP Socket】 — 單播、廣播、組播

在當前網絡通信中(TCP/IP也不例外)有三種通信模式:單播、廣播、組播(又叫多播, 個人感覺叫多播描述的有點不恰當),其中多播出現的時間最晚,但同時具備單播和廣播的優點,最具有發展前景。
通信方式分類:
1.單播:單臺主機與單臺主機之間的通信;
2.廣播:單臺主機與網絡中所有主機的通信;
3.組播:單臺主機與選定的一組主機的通信;

單播:
單播是網絡通信中最常見的,網絡節點之間的通信 就好像是人們之間的對話一樣。如果一個人對另外一個人說話,
那麼用網絡技術的術語來描述就是“單播”,此時信息的接收和傳遞只在兩個節點之間進行。
1. 單播的優點:
(1)服務器以及響應客戶端的請求;
(2)服務器能針對每個客戶端的不同請求發送不同的響應,容易顯示個性化服務;
2. 單播的缺點:
(1)服務器針對每個客戶機發送數據流,服務器流量=客戶機數量×客戶機流量;在客戶數量大、每個客戶機流量大的流媒體應用中服務器不堪重負;
3. 應用場景:
單播在網絡中得到了廣泛的應用,網絡上絕大部分的數據都 是以單播的形式傳輸的。例如:收發電子郵件、遊覽網頁時,必須與郵件服務器、
服務器建立連接,此時使用的就是單播通信方式;

廣播:
“廣播”可以比方爲:一個人通過廣播喇叭對在場的全體說話(他纔不管你是否樂意聽)。換句話說: 廣播是一臺主機對某一個網絡上的所有主機發送數據報包。
這個網絡可能是網絡,也可能時子網,還有可能是所有子網。
廣播有兩類:本地廣播和定向廣播:
定向廣播:將數據報包發送到本網絡之外的特定網絡的所有主機,然而,由於互聯網上的大部分路由器都不轉發定向廣播消息,所以這裏不深入介紹了
本地廣播:將數據報包發送到本地網絡的所有主機,IPv4的本地廣播地址爲“255.255.255.255”,路由器不會轉發此廣播;
1.廣播的優點:
(1)通信的效率高,信息一下子就可以傳遞到某一個網絡上的所有主機。
(2)由於服務器不用向每個客戶端單獨發送數據,所以服務器流量比較負載低;
2.廣播的缺點:
(1)非常佔用網絡的帶寬;
(2)缺乏針對性,也不管主機是否真的需要接收該數據, 就強制的接收數據;
3.應用場景:
(1)有線電視就是典型的廣播型網絡

組播:
”組播“可以比方爲:你對着大街喊:”是男人的來一下,一人發一百塊”,那麼男的過來,女就不會過來,因爲沒有錢發她不理你(組播:其中所有的男生就是一個組),
換句話說: 組播是一臺主機向指定的一組主機發送數據報包,因爲如果採用單播方式,逐個節點傳輸,有多少個目標節點,就會有多少次傳送過程,這種方式顯然效率 極低,是不可取
的;如果採用不區分目標、全部發送的廣播方式,雖然一次可以傳送完數據,但是顯然達不到區分特定數據接收對象的目的,又會佔用網絡帶寬。採用組播方式,既可以 實現一次傳送所
有目標節點的數據,也可以達到只對特定對象傳送數據的目的。
IP網絡的組播一般通過組播IP地址來實現。組播IP地址就是D類IP地址,即224.0.0.0至239.255.255.255之間的IP地址。
1.組播的優點:
(1)具備廣播所具備的所有優點;
(2)與單播相比,提供了發送數據報包的效率,與廣播相比,減少了網絡流量;
2.組播的缺點:
(1)與單播協議相比沒有糾錯機制,發生丟包錯包後難以彌補,但可以通過一定的容錯機制和QOS加以彌補;

應用實例:
1.UDP單播的例子
[java] view plaincopyprint?在CODE上查看代碼片派生到我的代碼片
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;

// 客戶端
public class ClientTest
{
private static final int MAXRECEIVED = 255;

public static void main(String[] args) throws IOException  
{  
    byte[] msg = new String("connect test successfully!!!").getBytes();  

    DatagramSocket client = new DatagramSocket();  

    InetAddress inetAddr = InetAddress.getLocalHost();  
    SocketAddress socketAddr = new InetSocketAddress(inetAddr, 8888);  

    DatagramPacket sendPacket = new DatagramPacket(msg, msg.length,  
            socketAddr);  

    client.send(sendPacket);  

    client.close();  
}  

}

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Arrays;

//服務端
public class ServerTest
{
private static final int MAXREV = 255;

public static void main(String[] args) throws IOException  
{  
    DatagramSocket server = new DatagramSocket(8888);  
    DatagramPacket recvPacket = new DatagramPacket(new byte[MAXREV], MAXREV);  

    while (true)  
    {  
        server.receive(recvPacket);  

        byte[] receiveMsg = Arrays.copyOfRange(recvPacket.getData(),  
                recvPacket.getOffset(),  
                recvPacket.getOffset() + recvPacket.getLength());  

        System.out.println("Handing at client "  
                + recvPacket.getAddress().getHostName() + " ip "  
                + recvPacket.getAddress().getHostAddress());  

        System.out.println("Server Receive Data:" + new String(receiveMsg));  

        server.send(recvPacket);  

    }  

}  

}

2.UDP廣播的例子
[java] view plaincopyprint?在CODE上查看代碼片派生到我的代碼片
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

//客戶端
public class BroadcastSender
{
public static void main(String[] args) throws IOException
{
byte[] msg = new String(“connection successfully!!!”).getBytes();
/*
* 在Java UDP中單播與廣播的代碼是相同的,要實現具有廣播功能的程序只需要使用廣播地址即可, 例如:這裏使用了本地的廣播地址
*/
InetAddress inetAddr = InetAddress.getByName(“255.255.255.255”);
DatagramSocket client = new DatagramSocket();

    DatagramPacket sendPack = new DatagramPacket(msg, msg.length, inetAddr,  
            8888);  

    client.send(sendPack);  
    System.out.println("Client send msg complete");  
    client.close();  
}  

}

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Arrays;

//服務端
public class BroadcastReceive
{
public static void main(String[] args) throws IOException
{

    DatagramPacket receive = new DatagramPacket(new byte[1024], 1024);  
    DatagramSocket server = new DatagramSocket(8888);  

    System.out.println("---------------------------------");  
    System.out.println("Server current start......");  
    System.out.println("---------------------------------");  

    while (true)  
    {  
        server.receive(receive);  

        byte[] recvByte = Arrays.copyOfRange(receive.getData(), 0,  
                receive.getLength());  

        System.out.println("Server receive msg:" + new String(recvByte));  
    }  

}  

}

3.UDP組播的例子
[java] view plaincopyprint?在CODE上查看代碼片派生到我的代碼片
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

//客戶端
public class MulticastSender
{
public static void main(String[] args) throws IOException
{
int port = 8888;
byte[] msg = “Connection successfully!!!”.getBytes();

    InetAddress inetRemoteAddr = InetAddress.getByName("224.0.0.5");  

    /* 
     * Java UDP組播應用程序主要通過MulticastSocket實例進行通信,它是DatagramSocket的是一個子類, 
     * 其中包含了一些額外的可以控制多播的屬性. 
     *  
     * 注意: 
     *  
     * 多播數據報包實際上可以通過DatagramSocket發送,只需要簡單地指定一個多播地址。 
     * 我們這裏使用MulticastSocket,是因爲它具有DatagramSocket沒有的能力 
     */  
    MulticastSocket client = new MulticastSocket();  

    DatagramPacket sendPack = new DatagramPacket(msg, msg.length,  
            inetRemoteAddr, port);  

    client.send(sendPack);  

    System.out.println("Client send msg complete");  

    client.close();  

}  

}

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.Arrays;

//服務端
public class MulticastReceive
{
public static void main(String[] args) throws IOException
{
InetAddress inetRemoteAddr = InetAddress.getByName(“224.0.0.5”);

    DatagramPacket recvPack = new DatagramPacket(new byte[1024], 1024);  

    MulticastSocket server = new MulticastSocket(8888);  

    /* 
     * 如果是發送數據報包,可以不加入多播組; 如果是接收數據報包,必須加入多播組; 這裏是接收數據報包,所以必須加入多播組; 
     */  
    server.joinGroup(inetRemoteAddr);  

    System.out.println("---------------------------------");  
    System.out.println("Server current start......");  
    System.out.println("---------------------------------");  

    while (true)  
    {  
        server.receive(recvPack);  

        byte[] recvByte = Arrays.copyOfRange(recvPack.getData(), 0,  
                recvPack.getLength());  

        System.out.println("Server receive msg:" + new String(recvByte));  
    }  

}  

}

原文鏈接:http://blog.csdn.net/dabing69221/article/details/17286441#t1

發佈了39 篇原創文章 · 獲贊 14 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章