首页 > Python基础教程 > Python网络编程
阅读:2,139
UDP多点广播(多播)原理及实现
通过多点广播,可以将数据报以广播方式式发送到多个客户端。
若要使用多点广播,则需要将数据报发送到一个组目标地址,当数据报发出后,整个组的所有主机都能接收到该数据报。IP 多点广播(或多点发送)实现了将单一信息发送给多个接收者的广播,其思想是设置一组特殊的网络地址作为多点广播地址,每一个多点广播地址都被看作一个组,当客户端需要发送和接收广播信息时,加入该组即可。
IP 协议为多点广播提供了特殊的 IP 地址,这些 IP 地址的范围是 224.0.0.0~239.255.255.255。多点广播示意图如图 1 所示。
图 1 多点广播示意图
从图 1 中可以看出,当 socket 把一个数据报发送到多点广播 IP 地址时,该数据报将被自动广播到加入该地址的所有 socket。该 socket 既可以将数据报发送到多点广播地址,也可以接收其他主机的广播信息。
在创建了 socket 对象后,还需要将该 socket 加入指定的多点广播地址中,socket 使用 setsockopt() 方法加入指定组。
如果创建仅用于发送数据报的 socket 对象,则使用默认地址、随机端口即可。但如果创建接收数据报的 socket 对象,则需要将该 socket 对象绑定到指定端口;否则,发送方无法确定发送数据报的目标端口。
支持多点广播的 socket 还可设置广播信息的 TTL(Time-To-Live),该 TTL 参数用于设置数据报最多可以跨过多少个网络:
下面程序使用 socket 实现了一个基于广播的多人聊天室。程序只需要一个 socket、两个线程,其中 socket 既用于发送数据,也用于接收数据;主线程负责读取用户的键盘输入内容,并向 socket 发送数据,子线程则负责从 socket 中读取数据。
第 18 行代码将该 socket 对象添加到指定的多点广播 IP 地址。至于程序中使用 socket 发送和接收数据报的代码,与前面的程序并没有区别,故此处不再赘述。
若要使用多点广播,则需要将数据报发送到一个组目标地址,当数据报发出后,整个组的所有主机都能接收到该数据报。IP 多点广播(或多点发送)实现了将单一信息发送给多个接收者的广播,其思想是设置一组特殊的网络地址作为多点广播地址,每一个多点广播地址都被看作一个组,当客户端需要发送和接收广播信息时,加入该组即可。
IP 协议为多点广播提供了特殊的 IP 地址,这些 IP 地址的范围是 224.0.0.0~239.255.255.255。多点广播示意图如图 1 所示。
图 1 多点广播示意图
从图 1 中可以看出,当 socket 把一个数据报发送到多点广播 IP 地址时,该数据报将被自动广播到加入该地址的所有 socket。该 socket 既可以将数据报发送到多点广播地址,也可以接收其他主机的广播信息。
在创建了 socket 对象后,还需要将该 socket 加入指定的多点广播地址中,socket 使用 setsockopt() 方法加入指定组。
如果创建仅用于发送数据报的 socket 对象,则使用默认地址、随机端口即可。但如果创建接收数据报的 socket 对象,则需要将该 socket 对象绑定到指定端口;否则,发送方无法确定发送数据报的目标端口。
支持多点广播的 socket 还可设置广播信息的 TTL(Time-To-Live),该 TTL 参数用于设置数据报最多可以跨过多少个网络:
- 当TTL的值为 0 时,指定数据报应停留在本地主机中;
- 当TTL的值为 1 时,指定将数据报发送到本地局域网中;
- 当TTL 的值为 32 时,意味着只能将数据报发送到本站点的网络上;
- 当TTL 的值为 64 时,意味着数据报应被保留在本地区;
- 当TTL 的值为 128 时,意味着数据报应被保留在本大洲;
- 当TTL 的值为 255 时,意味着数据报可被发送到所有地方;
在默认情况下,TTL 的值为1。
从图 1 中可以看出,使用 socket 进行多点广播时所有的通信实体都是平等的,它们都将自己的数据报发送到多点广播IP地址,并使用 socket 接收其他人发迭的广播数据报。下面程序使用 socket 实现了一个基于广播的多人聊天室。程序只需要一个 socket、两个线程,其中 socket 既用于发送数据,也用于接收数据;主线程负责读取用户的键盘输入内容,并向 socket 发送数据,子线程则负责从 socket 中读取数据。
import time, socket, threading, os # 定义本机IP地址 SENDERIP = '192.168.1.88' # 定义本地端口 SENDERPORT = 30000 # 定义本程序的多点广播IP地址 MYGROUP = '230.0.0.1' # 通过type属性指定创建基于UDP协议的socket s = socket.socket(type=socket.SOCK_DGRAM) # 将该socket绑定到0.0.0.0的虚拟IP s.bind(('0.0.0.0', SENDERPORT)) # ① # 设置广播消息的TTL(Time-To-Live) s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 64) # 设置允许多点广播使用相同的端口 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 将socket进入广播组 status = s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(MYGROUP) + socket.inet_aton(SENDERIP)) # 定义从socket读取数据的方法 def read_socket(sock): while True: data = sock.recv(2048) print("信息: ", data.decode('utf-8')) # 以read_socket作为target启动多线程 threading.Thread(target=read_socket, args=(s, )).start() # 采用循环不断读取键盘输入,并输出到socket中 while True: line = input('') if line is None or line == 'exit': break os._exit(0) # 将line输出到socket中 s.sendto(line.encode('utf-8'), (MYGROUP, SENDERPORT))上面主程序中,第 10 行代码先创建了一个基于 UDP 协议的 socket 对象,由于需要使用该 socket 对象接收数据报,所以将该 socket 绑定到固定端口(由于只需要绑定到固定端口,因此程序中 ① 号代码使用了 0.0.0.0 这个虚拟 IP 地址)。
第 18 行代码将该 socket 对象添加到指定的多点广播 IP 地址。至于程序中使用 socket 发送和接收数据报的代码,与前面的程序并没有区别,故此处不再赘述。
所有教程
- socket
- Python基础教程
- C#教程
- MySQL函数
- MySQL
- C语言入门
- C语言专题
- C语言编译器
- C语言编程实例
- GCC编译器
- 数据结构
- C语言项目案例
- C++教程
- OpenCV
- Qt教程
- Unity 3D教程
- UE4
- STL
- Redis
- Android教程
- JavaScript
- PHP
- Mybatis
- Spring Cloud
- Maven
- vi命令
- Spring Boot
- Spring MVC
- Hibernate
- Linux
- Linux命令
- Shell脚本
- Java教程
- 设计模式
- Spring
- Servlet
- Struts2
- Java Swing
- JSP教程
- CSS教程
- TensorFlow
- 区块链
- Go语言教程
- Docker
- 编程笔记
- 资源下载
- 关于我们
- 汇编语言
- 大数据
- 云计算
- VIP视频