IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Java网络编程(八)—— 组播和MulticastSocket -> 正文阅读

[网络协议]Java网络编程(八)—— 组播和MulticastSocket

Java网络编程(八)—— 组播和MulticastSocket

什么是组播

网络数据传播按照接收者的数量,可分为以下3种方式。

  • 单播:提供点对点的通信。发送者每次发送的数据有着唯一的目的地址,只被一个接收者接收。前面介绍的TCP Socket和 UDP Socket都只支持单播。
  • 广播:发送者每次发送的数据可以被传播范围内的所有接收者接收。最典型的就是电视台采用广播方式。从电视台发射的信号被发送到传播范围内的每个点。不管电视机有没有打开,信号都能到达每台电视机。IP协议支持广播,但是由于广播会大大增加网络的数据流量,因此对广播的使用作了严格的限制。路由器可以限制对本地网络或子网的广播,并禁止对整个Internet的广播。此外,应该禁止广播那些占用高带宽的数据,如音频和视频数据。试想如果一个实时视频流被广播给上亿的Internet用户,那么将使Internet严重超载,甚至崩溃。
  • 组播:发送者每次发送的数据可以被小组内的所有接收者接收。组播的接收范围介于单播和广播之间。对特定话题感兴趣的主机加入到同一个组播组,向这个组发送的数据会到达组内所有的主机,但不会到达组外的主机。

当发送者要给1000个接收者发送同样的数据时,如果采用单播,那么在发送方数据被复制1000份,分别传送给每个接收者,这种传播方式效率很低,因为它对数据进行了不必要的复制,浪费了许多网络带宽。如果采用组播,则可以大大提高传输效率,路由器会动态决定组播数据的路由,只在必要时才复制数据。

例如下面的例子,主机1把数据组播给主机2、主机3、主机4和主机5。数据只在路由器2和路由器3上被复制,在其余节点上无须复制数据。在从主机1到路由器2的传输路径上,数据只需传送一次。如果采用单播方式,那么数据在主机1上就被复制4次再发送。在从主机1到路由器2的传输路径上,数据需要重复传送4次。

在这里插入图片描述

组播组内的所有主机共享同一个地址,这种地址称为组播地址。组播地址是范围在224.0.0.0~239.255.255.255之间的P地址。此范围内的所有地址的前4个二进制位.都是“1110”。组播地址也被称为D类IP地址,与其他的A类、B类和C类地址相区别。组播组是开放的,主机可以在任何时候进入或离开组。

大多数组播数据为音频或视频,这些数据一般都很大,如果部分数据在传输途中丢失,接收方仍然能识别信号。因此组播数据通过UDP发送,虽然不可靠,但比面向连接的TCP的传输速度快3倍以上。

组播与单播UDP的区别在于,前者必须考虑TTL (Time To Live,,生存时间)值。TTL通过限制IP包被丢弃前通过的路由器数目,来决定IP包的生存时间。IP包每通过一个路由器,TTL就减1,当TTL变为0时,这个包就被丢弃。TTL的一个作用是防止配置有误的路由器把包在路由器之间无限地来回传递,还有一个作用是限制组播的地理范围。 例如,当TTL为16时,包限制在本地区域内传播,当TTL为255时,包将发送到整个世界。不过,TTL 并不能精确地决定包传播的地理范围。一般情况下,接收方离得越远,包要经过的路由器就越多,TTL值小的包不会比TTL值大的包传播得更远。值得注意的是,无论TTL取什么值,如果包被发送给地址为224.0.0.0~224.0.0.255之间的组播组,则包只会在本地子网内传播,而不会被转发到其他网络。

如果要收发本地子网以外的组播数据,要求本地网上配置了组播路由器(mrouter)。可以从网络管理员那里了解是否配置了mrouter,也可以运行命令“ping all-routers.mcast.net”,如果有路由器响应,则说明网络上有mrouter。

此外,即使子网上配置了mrouter,还是不能保证收发Internet上每一台主机的组播数据。要让包到达组播组内的任何地址,要求在发送主机和接收主机之间存在一条由多个mrouter组成的传输路径。如果不存在这样的路径,包就无法到达每个接收主机。

MulticastSocket类

总述

java.net.MulticastSocket具有组播的功能,它是 DatagramSocket的子类,和 DatagramSocket一样,MulticastSocket也与 DatagramPacket搭配使用,DatagramPacket用来存放接收和发送的组播数据报。
如果要接收组播数据报,只需创建一个MulticastSocket,把它加入到组播组,就能接收发送到该组的组播数据报。

发送组播数据报与发送单播数据报非常相似,只需创建一个MulticastSocket,无须把它加入到组播组(当然也可以把它加入到组播组),就能向一个组播组发送数据。发送组播数据报与发送单播数据报的区别在于,前者可以先调用setTimeToLive()方法,来设置组播数据报的TTL生存时间。

在开始学习MulticastSocket类之前,最好先学一一下UDP和MulticastSocket、DatagramPacket,具体可以看这两篇博客:《Java网络编程(六)—— UDP编程(一)》《Java网络编程(七)—— UDP编程(二)》

构造方法

MulticastSocket有下面三种构造方法

public MulticastSocket() throws SocketException
public MulticastSocket(int port) throws SocketException
public MulticastSocket(SocketAddress bindAddress) throws SocketException

第一个不带参数的构造方法使MulticastSocket与一个匿名端口绑定,对于只发送组播数据的程序,可以使用这种构造方法。其余两个构造方法使 MulticastSocket绑定到特定的已知端口,对于接收组播数据的程序,可以使用这两种构造方法,从而使发送方发送的组播数据可以方便地寻址到该MulticastSocket。

对于第三个构造方法,如果把参数设为null,那么MulticastSocket不与任何本地端口绑定,程序接下来需要再调用bind()方法。例如下面的方式

MulticastSocket ms = new MulticastSocket(null);
ms.setReuseAddress(false);//设置MulticastSocket的选项,禁止重用绑定地址
SocketAddress address = new InetSocketAddress(3000);
ms.bind(address);

与组播组通信

MulticastSocket使用以下四种操作与组播组进行通信:

1. 加入组播组: joinGroup()
2. 向组播组成员发送数据报: send()
3. 接收发送到组播组的数据报: receive()
4. 离开组播组:leaveGroup()

send()和 receive()方法直接从父类DatagramSocket中继承而来,joinGroup()和 leaveGroup()方法是 MulticastSocket专有的。需要注意的是,MulticastSocket必须加入组后才能接收发往该组的数据,此外,必须加入组后才能离开该组。不过,MulticastSocket向一个组发送数据并不一定要先加入该组。

joinGroup()方法用于加入到一个组播组。一个 MulticastSocket可以多次调用joinGroup()方法,加入到多个组播组。此外,同一个主机上的多个MulticastSocket,或者主机的同一程序内的多个MulticastSocket可以加入到同一个组播组,每个MulticastSocket都会接收到发往该组的数据。joinGroup()方法有两种重载形式:

public void joinGroup(InetAddress address)throws IOException
public void joinGroup(SocketAddress address,NetworkInterface interface) throws IOException

在第一个joinGroup()方法中,参数address指定一个组播IP地址,该地址必须位于224.0.0.0~239.255.255.255之间,否则该方法会抛出IOException。在第二个joinGroup()方法中,参数address指定组播地址,参数interface指定网络接口。利用此方法,可以限定MulticastSocket只接收来自某个网络接口的组播数据报。

leaveGroup()方法用于离开一个组播组。MulticastSocket离开了一个组后,就不能再接收到发往该组的数据报。它有以下两种重载形式:

public void leaveGroup(InetAddress address)throws IOException
public void leaveGroup(SocketAddress address,NetworkInterface interface) throws IOException

参数address指定要离开的组播地址,如果试图离开的地址不是组播地址,leaveGroup()方法会抛出IOException。但是,如果 MulticastSocket 离开一个并未加入的组,leaveGroup()方法不会抛出任何异常。参数interface指定不再希望接受来自某个网络接口的组播数据报。MulticastSocket有可能一开始加入了所有网络接口的组播组,随后可通过第二个leaveGroup()方法离开其中的一个网络接口中的组。

设置和获取 MulticastSocket 属性

MuliticastSocket提供了两组用于设置和读取网络接口的方法。MuliticastSocket只会对该网络接口中的组收发组播数据:

1第1组方法
public void setInterface(InetAddress address)throws SocketException
public InetAddress getInterface()throws SocketException

//第2组方法
public void setNetworkInterface(NetworkInterface interface)throws SocketException
public NetworkInterface getNetworkInterface( throws SocketException

以上两组方法作用相同。区别在于第一组方法用InetAddress类表示网络接口,而第二组方法用NetworkInterface类表示网络接口。一个NetworkInterface对象表示一个网络接口,它有一个唯一的域名,并且可以包含一个或多个IP地址。

MuliticastSocket类提供了设置和读取TTL属性的方法:

public void setTimeToLive(int ttl) throws IOException
public int getTimeToLive() throws IOException

MuliticastSocket示例

使用MuliticastSocket持续向一个IP地址为224.0.0.1的组播组发送数据,数据是当前的时间,MuliticastSocket发送和接收数据与DatagramSocket几乎相同,不同的是,接收数据报就需要加入这个分组,不过,作为发送方可选择加入这个分组,也可以选择不加入

MuliticastSocket 接收方

public class MulticastReceiver {
    public static void main(String[] args) throws Exception {
        InetAddress group = InetAddress.getByName("224.0.0.1");
        int port = 5555;
        MulticastSocket ms = null;
        try {
            ms = new MulticastSocket(port);
            ms.joinGroup(group);//加入到组播组
            byte[] buffer = new byte[8192];
            while (true) {
                DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
                ms.receive(dp);//接收组播数据报
                String s = new String(dp.getData(), 0, dp.getLength());
                System.out.println(s);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally
        {
            if (ms !=null)
            {
                try
                {
                    ms.leaveGroup(group);
                    ms.close();
                } catch (IOException e) { }
            }
        }
    }
}

在这里插入图片描述

MuliticastSocket 发送方

public class MulticastSender {

    public static void main(String[] args) throws IOException {
        InetAddress group = InetAddress.getByName("224.0.0.1");
        int port = 5555;
        MulticastSocket ms = null;

        try {
            ms = new MulticastSocket(port);
            ms.joinGroup(group);//加入到组播组
            while (true) {
                String message = "Hello " + new java.util.Date();
                byte[] buffer = message.getBytes();
                DatagramPacket dp = new DatagramPacket(buffer, buffer.length, group, port);
                ms.send(dp);//发送组播数据报
                System.out.println("发送数据报给" + group + ":" + port);
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ms != null) {
                try {
                    ms.leaveGroup(group);
                    ms.close();
                } catch (IOException e) {
                }

            }
        }
    }
}

在这里插入图片描述

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:59:31  更:2021-11-09 20:00:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:41:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码