美文网首页
Python 实现udp组播

Python 实现udp组播

作者: 逐风细雨 | 来源:发表于2022-03-24 18:03 被阅读0次

    有关知识
    基本概念
    单播:两个主机间单对单的通信
    广播:一个主机对整个局域网上所有主机上的数据通信(网络地址全1)
    单播和广播是两个极端,要么对一个主机进行通信,要么对整个局域网的主机进行通信

    组播:实际情况下,经常需要对一组特定的主机进行通信,而不是所有局域网上的主机
    IP组播(也称多址广播或多播),是一种允许一台或多台主机发送数据包到多台主机的TCP/IP网路技术。

    多播是 IPv6 数据包的 3 种基本目的地址类型之一,多播是一点对多点的通信, IPv6 没有采用 IPv4 中的组播术语,而是将广播看成是多播的一个特殊例子。

    多播组只能用UDP 或者原始套接字实现,不能用TCP。

    广播地址
    在使用TCP/IP 协议的网络中,主机标识段host ID 为全1 的IP 地址为广播地址,广播的分组传送给host ID段所涉及的所有计算机。

    传输层只有UDP可以广播 。

    组播地址
    IP 组播通信必须依赖于 IP 多播地址,在 IPv4 中它是一个 D 类 IP 地址,范围从 224.0.0.0 到 239.255.255.255,并被划分为局部链接多播地址、预留多播地址和管理权限多播地址3类:

    局部链接多播地址范围在 224.0.0.0~224.0.0.255,这是为路由协议和其它用途保留的地址,路由器并不转发属于此范围的IP包;

    预留多播地址为 224.0.1.0~238.255.255.255,可用于全球范围(如Internet)或网络协议;

    管理权限多播地址为 239.0.0.0~239.255.255.255,可供组织内部使用,类似于私有 IP 地址,不能用于 Internet,可限制多播范围。

    组播地址与MAC地址的映射
    使用同一个 IP 多播地址接收多播数据包的所有主机构成了一个主机组,也称为多播组。一个多播组的成员是随时变动的,一台主机可以随时加入或离开多播组,多播组成员的数目和所在的地理位置也不受限制,一台主机也可以属于几个多播组。

    这个我们可以这样理解,多播地址就类似于 QQ 群号,多播组相当于 QQ 群,一个个的主机就相当于群里面的成员。

    设备驱动程序就必须接收所有多播数据帧,然后对它们进行过滤,这个过滤过程是网络驱动或IP层自动完成。(设备驱动程序会对多播数据进行过滤,将其发到相应的位置)

    组播应用
    单点对多点应用
    点对多点应用是指一个发送者,多个接收者的应用形式,这是最常见的多播应用形式。典型的应用包括:媒体广播、媒体推送、信息缓存、事件通知和状态监视等。

    多点对单点应用
    多点对点应用是指多个发送者,一个接收者的应用形式。通常是双向请求响应应用,任何一端(多点或点)都有可能发起请求。典型应用包括:资源查找、数据收集、网络竞拍、信息询问等。

    多点对多点应用
    多点对多点应用是指多个发送者和多个接收者的应用形式。通常,每个接收者可以接收多个发送者发送的数据,同时,每个发送者可以把数据发送给多个接收者。典型应用包括:多点会议、资源同步、并行处理、协同处理、远程学习、讨论组、分布式交互模拟(DIS)、多人游戏等。
    参考的文章 https://www.cnblogs.com/schips/p/12552534.html

    下面实现一个python(3.8)的演示原理的版本
    功能:1.每个客户端随机生成一个id当做标识
    2.每个客户端绑定本机一个Ip的端口(在同一台机器上面可以启动多个脚本)
    3. 加入同一网段的一个组播地址
    4. 启动后,发送一个消息
    5. 收到消息后,根据id判断消息是否是自己发出的,其它客户端的时候回一个消息

    import socket
    import random
    from loguru import logger
    
    HOST = "10.2.15.103"
    DES_IP = "239.255.255.252"
    PORT = 23456
    msg = "大家好,我上线了"
    # 生成随机标识
    client_id = random.randint(1000, 2000)
    
    # 创建UDP socket
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    # 允许端口复用
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 绑定监听多播数据包的端口
    s.bind((HOST, PORT))
    # 声明该socket为多播类型
    s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
    # 加入多播组,组地址由第三个参数制定
    s.setsockopt(
        socket.IPPROTO_IP,
        socket.IP_ADD_MEMBERSHIP,
        socket.inet_aton(DES_IP) + socket.inet_aton(HOST)
    )
    s.setblocking(False)
    logger.debug(f"本机随机ID:{client_id}")
    s.sendto(f"client_id:{client_id}->大家好".encode(), (DES_IP, PORT))
    
    while True:
        try:
            data, address = s.recvfrom(2048)
            data = data.decode()
            logger.debug(f'收到的信息->address:{address} data->{data}')
            # 收到好信息好,回一个你也好,并过滤掉自己发出的信息
            if "大家好" in data and f"client_id:{str(client_id)}" not in data:
                s.sendto(f"client_id:{client_id}->你也好".encode(), (DES_IP, PORT))
        except Exception as e:
            logger.exception("处理异常")
            pass
    

    启动两个脚本以后效果如下:


    企业微信截图_16481157267150.png

    ps:在相同网段可以很容易实现组播。跨网段组播必须打开三层交换机的组播路由协议,一般是PIM 稀疏模式,一般三层交换机的默认配置是没有打开组播路由的。(待实践)

    相关文章

      网友评论

          本文标题:Python 实现udp组播

          本文链接:https://www.haomeiwen.com/subject/mmkljrtx.html