Python3组播通信编程实现教程(发送者+接收者)

一、说明

1.1 标准组播解释

通信分为单播、多播(即组播)、广播三种方式

单播指发送者发送之后,IP数据包被路由器发往目的IP指定的唯一一台设备的通信形式,比如你现在与web服务器通信就是单播形式

广播指发送者发送之后,IP数据包被路由器发给与其连接的所有设备的通信形式

组播指发送者发送之后,IP数据包被路由器发往目的IP对应组播组名下所有主机的通信形式

1.2 个人理解组播解释

对于标准的组播解释,说明似乎还算是清楚的,但具体到技术就有很多问题。比如我将数据包发往一个组播地址,这个组播地址对应一台物理设备吗?如果不是一台物理设备那谁依据什么向哪些主机发送该数据包等等。

结合各资料和自己测试的情况总结出了以下几点:

1) 编写发送程序:组播数据包是且只是目的IP是组播保留地址的UDP数据包,与正常UDP数据包的区别只是其目的IP是组播保留IP

2) 发送数据包主机:网卡在看到目的IP是组播保留IP后,自动将目的mac地址改成组播mac地址然后向其各端口都发送出去

3) 交换机:交换机在接收到数据包之后,通过目的mac地址认识到这是一个组播数据包,修改源mac为自己mac、保持目的mac为组播mac不变向其各端口都发送出去(交换机对组播包的处理和广播包应该是一样的,或者说对于交换机只有单播包和广播包)

4) 路由器:路由器在接收到数据包之后,通过目的mac地址或目的ip地址认识到这是一个组播数据包,修改源mac为自己mac、保持目的mac为组播mac不变,保持源IP不变、保持目的IP为组播保留IP不变,依照与路由表类似的“组播组地址表”向与目的IP匹配的一个或多端口将数据包发送出去

5) 接收数据包主机:接收数据包主机要想接收到发送主机发送的数据包,首先他要(向路由器说明)加入发送者发往的组播组,然后他要在本地启动一个进程监听发送者发往的端口

6) 组播需要硬件支持,有些路由器是不支持组播的,就直观感受看如果在全球实现组播那维护“组播组地址表”会给路由器带来很大负担路由大厂商应该也不是很愿意支持组播;也就是说理论上组播可以在广域网上实现,但其实一般只在局域网中(能够)使用。

通信举例如下:

发送者S(假设使用组播地址为234.2.2.2,使用组播端口为23456)----发送者向234.2.2.2:23456发送一个UDP数据包Packet1

接收者R1(假设其IP地址为192.168.220.128)----第一步通过setsockopt加入组播组(234.2.2.2);第二步启动进程监听192.168.220.128:23456

接收者R2(假设其IP地址为192.168.220.129)----第一步通过setsockopt加入组播组(234.2.2.2);第二步启动进程监听192.168.220.129:23456

最终效果----发送者发往234.2.2.2:23456的udp数据包,R1的23456端口收到一份Packet1,R2的23456端口收到一份Packet1

1.3 谁是服务端引发的混乱

我在前面一直使用“发送者”、“接收者”,而没有使用“服务端”、“客户端”,因为“服务端”和“客户端”在组播中容易引发混乱。

在我们一般的socket编程中都是服务端去bind;但在组播中是反过来,客户端(接收者)去bind,而发送者(服务端)是不用去bind的(注意是不用而不是不能,你非要bind也是可以的,bind和不bind只是使用固定端口还是使用随机端口的区别)。

有些小伙伴意识到了这个问题,为了与习惯一致,所以直接将发送者称为客户端,接收者称为服务端。

其实这种叫法是不合适的,以初高中常见的电脑课场景为例:老师控制所有电脑显示老师的电脑操作,这时作为发送者的老师电脑从认知上确实应该是服务端而不是客户端才对。

如果你读了半天没听懂这里在说什么,那不必在意,记得组播中尽里使用“发送者”和“接收者”,少用“服务端”和“客户端”就对了。

二、程序实现

2.1 程序代码

发送者代码:

import time
import socket

# 组播组IP和端口
mcast_group_ip = ‘234.2.2.2‘
mcast_group_port = 23456

def sender():
    # 建立发送socket,和正常UDP数据包没区别
    send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    # 每十秒发送一遍消息
    while True:
        message = "this message send via mcast !"
        # 发送写法和正常UDP数据包的还是完全没区别
        # 猜测只可能是网卡自己在识别到目的ip是组播地址后,自动将目的mac地址设为多播mac地址
        send_sock.sendto(message.encode(), (mcast_group_ip, mcast_group_port))
        print(f‘{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: message send finish‘)
        time.sleep(10)

if __name__ == "__main__":
    sender()

接收者代码:

import struct
import time
import socket

# 组播组IP和端口
mcast_group_ip = ‘234.2.2.2‘
mcast_group_port = 23456

def receiver():
    # 建立接收socket,和正常UDP数据包没区别
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    # 获取本地IP地址
    local_ip = socket.gethostbyname(socket.gethostname())
    # 监听端口,已测试过其实可以直接bind 0.0.0.0;但注意不要bind 127.0.0.1不然其他机器发的组播包就收不到了
    sock.bind((local_ip, mcast_group_port))
    # 加入组播组
    mreq = struct.pack("=4sl", socket.inet_aton(mcast_group_ip), socket.INADDR_ANY)
    sock.setsockopt(socket.IPPROTO_IP,socket.IP_ADD_MEMBERSHIP,mreq)

    # 允许端口复用,看到很多教程都有没想清楚意义是什么,我这里直接注释掉
    # sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 设置非阻塞,看到很多教程都有也没想清楚有什么用,我这里直接注释掉
    # sock.setblocking(0)
    while True:
        try:
            message, addr = sock.recvfrom(1024)
            print(f‘{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Receive data from {addr}: {message.decode()}‘)
        except :
            print("while receive message error occur")

if __name__ == "__main__":
    receiver()

2.2 运行截图

发送者截图:

接收者运行截图:

参考:

https://blog.csdn.net/ztb3214/article/details/19285363

https://blog.csdn.net/s_lisheng/article/details/74938534?locationNum=10&fps=1

http://blog.sina.com.cn/s/blog_69c81c3e0102x9pm.html

原文地址:https://www.cnblogs.com/lsdb/p/9408947.html

时间: 2024-10-09 22:51:52

Python3组播通信编程实现教程(发送者+接收者)的相关文章

RPC、RMI与MOM与组播 通信原理

转:http://blog.csdn.net/you12345678901234567/article/details/7625797 远程过程调用(RPC): 即对远程站点机上的过程进行调用.当站点机A上的一个进程调用另一个站点机上的过程时,A上的调用进程挂起,B上的被调用过程执行,并将结果返回给调用进程,使调用进程继续执行[B上的被调用过程的参数和执行结果在调用和被调用进程之间是通过消息传递来实现的,表现为C/S关系] 为实现不同站点机上的RPC,调用和被调用进程各方都要保留一个用于存放过程

组播 java编程

原文地址:http://blog.sina.com.cn/s/blog_49843aeb0100i0bc.html 组播 作用:主机间通信使用.路由间通信使用 概念:IP组播技术,是一种允许一台或多台主机(组播源)发送单一数据包到多台主机(一次的,同时的)的TCP/IP网络技术,是一点对多点的通信 为什么用它:在网络多媒体广播的应用中,当需要将一个节点的信号传送到多个节点时,无论是采用重复点对点通信方式,还是采用广播方式,都会严重浪费网络带宽,只有组播才是最好的选择.组播能使一个或多个组播源只把

组播通信

考虑一个场景,某公司用远程视频会议软件开一个会议,BOSS在总部发言而其他分部员工接收视频,这时如果还是使用单播模式的话,总部的视频将通过网络传给每个分部员工,它有一个特点是有多少客户端就需要传送多少次,当客户端的数量越来越大时可能会导致网络阻塞,而且这种传送效率极低.于是引入了组播通信概念. 如图,上为单播模式,S1向S2.S3和S4发送消息时必须发送三次,且每次都是从S1出发到各自目的地,传输效率低且浪费网络资源.下图为组播模式,S1向S2.S3和S4发送消息只需S1发送一次到路由器,连接S

IP组播技术介绍及实现例子

引 言 近年来,随着Internet的迅速普及和爆炸性发展,在Internet上产生了许多新的应用,其中不少是高带宽的多媒体应用,譬如网 络视频会议.网络音频/视频广播.AOD/VOD.股市行情发布.多媒体远程教育.CSCW协同计算.远程会诊.这就带来了带宽的急剧消耗和网络拥挤问 题.为了缓解网络瓶颈,人们提出各种方案,归纳起来,主要包括以下四种: ●增加互连带宽: ●服务器的分散与集群,以改变网络流量结构,减轻主干网的瓶颈: ●应用QoS机制,把带宽分配给一部分应用: ●采用IP Multic

CCNP路由实验之十 组播(多播)

??                    CCNP路由实验之十 组播(多播) 单播(Unicast):网络节点之间的通信通讯的模式是"一对一"的.此时信息的接收和传递仅仅在两个节点之间进行.比如.你在收发电子邮件.浏览网页时,必须与邮件server.Webserver建立连接,此时使用的就是单播传输数据方式.网络中的交换机和路由器对数据仅仅进行转发不进行复制. 假设10个客户机须要同样的数据,则server须要逐一传送.反复10次同样的工作. 但因为其能够针对每一个客户的及时响应.所

SylixOS组播使用

1. 概述 本文主要介绍如何在SylixOS上使用组播功能. 2. SylixOS组播设置 组播传输,即在发送者和每一接收者之间实现点对多点网络连接通信.正常大家会参考Linux使用组播的方法:把本机加入组播地址,即本机网卡作为组播成员,只有加入组才能收到组播消息.通过setsockopt设置加入组播,这样便可以接收组播信息.Linux参考代码如程序清单 2.1和程序清单 2.2所示. 程序清单 2.1  mcastserver #include <sys/types.h> #include

网络通信:单播、广播、组播

本文目录: 一.网络通信的分类.他们的定义和特点. 二.单播.广播.组播的传输信息的网络拓扑模型. 三.单播.广播.组播的编程实例. 一.网络通信的分类.他们的定义和特点. 二.单播.广播.组播的传输信息的网络拓扑模型. (一)单播 如图8-1 所示,网络中存在信息发送者Source,UserA 和UserC 提出信息需求,网络采用单播方式传输信息.                                                  单播传输特点归纳如下: * Source 向每个

组播的应用和实现

一.引言 1.1. 问题的引出 近年来,随着网络技术的发展,使得各种单一媒体相继成为网络传输中的数据,进而各种媒体的融合使得网络多媒体运用层出不穷.目前,在Internet上产生了许多新的应用,其中不少是高带宽的多媒体应用,譬如网络视频会议 (可视化IP电话会议系统).网络音频/视频广播.多媒体远程教育.远程会诊,而传统网络最初是为数据传输而设计的,是典型的点点通信模式,是为保证数据可靠传输而设计的,所用的传输协议多为点到点的协议.其所具有的特点将增加网络发送负载,带来网络延时.这就带来了带宽的

组播原理

原文地址:http://linux.chinaitlab.com/administer/5573.html 摘要: 本文可做为TCP/IP组播技术的入门材料,文中介绍了组播通 信的概念及原理,以及用于组播应用编程的Linux API的详细资料.为了使读者更加完整的了解Linux 组播的整体概念,文中对实现该技术的核心函数也做了介绍.在文章的最后给出了一个简单的C语言套接字编程例子,说明如何创建组播应用程序. 一.导言 在网络中,主机间可以用三种不同的地址进行通信: 单播地址(unicast):即