1.广播
前面我们所写的所有代码都只能实现点对点的通信,除非使用多线程或多进程的手段来实现一对多的通信效果。如何不使用进程线程的手段来实现给局域网中所有的主机发送一对多的广播效果呢?可以使用Linux中的广播机制。
1.1特点:
- 不需要循环给每一个主机发送数据,而是在同一个局域网中所有的主机都能收到广播信息
- 只需要向广播地址发送数据即可,整个局域网中的主机都能收到该信息
- 只有UDP协议才支持这个骚操作
1.2广播地址:
$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.100.3 netmask 255.255.255.0 broadcast 192.168.100.255
inet6 fe80::215:5dff:fe15:f945 prefixlen 64 scopeid 0x20<link>
ether 00:15:5d:15:f9:45 txqueuelen 1000 (Ethernet)
RX packets 5222 bytes 1636434 (1.6 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 250 bytes 20726 (20.7 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
inet 192.168.100.3 // 当前主机IP地址
netmask 255.255.255.0 // 子网掩码
broadcast 192.168.100.255 // 广播地址
只需要把数据发送到 广播地址 (192.168.100.255) 中即可实现向局域网中所有的主机发送,在局域网中所有的主机主要愿意都可以从 广播地址 (192.168.100.255)中收到消息。
而255.255.255.255是所有网段局域网的广播地址
思路:
由于Linux 下创建的套接字默认是没有打开广播功能的,所以需要手动开启。
- 创建UDP套接字
- 设置广播属性
- 往广播地址中发送数据即可
关键代码:
// 使能广播属性
int on = 1;
setsockopt(sock_fd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));
addr.sin_family = AF_INET;
addr.sin_port = htons(65000);
addr.sin_addr.s_addr = inet_addr("192.168.100.255");
2.组播
组播是处于单播与广播之间的折中选择,在一个局域网内,把某些主机加入到多播组中,并设置一个地址给多播组,这样我们就只需要把数据往该多播组的地址上发送即可,加入该组的所有主机都会收到数据。
2.1特点:
- 广播方式发给所有的主机是,如果有太多的数据占用网络带宽,将很容易造成网络风暴影响通信
- 在组播前必须为多播组设置一个IP地址,该IP地址必须是D类网络地址。
- 只有UDP协议支持组播功能。
2.2IP地址分类
网络字节 主机字节 范围
A类地址: 1字节 3字节 1.0.0.1 --- 126.255.255.255
B类地址: 2字节 2字节 128.0.0.1 --- 191.255.255.255
C类地址: 3字节 1字节 192.0.0.1 --- 223.255.255.255
D类地址,不区别网络字节与主机字节 224.0.0.1 --- 239.255.255.255
思路:
- 创建UDP套接字
- 配置组播结构体
- 加入组播
- 等待消息
如何加入组播:
//定义一个组播结构体
struct ip_mreq v;
bzero(&v,sizeof(v));
//指明多播组的IP地址
inet_pton(AF_INET,"224.0.0.100",&v.imr_multiaddr);
inet_pton(AF_INET,"192.168.100.2",&v.imr_interface);
//加入组播属性
setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&v,sizeof(v));