> 文章列表 > 4.34、组播(多播)

4.34、组播(多播)

4.34、组播(多播)

4.34、多播

  • 1.组播(多播)的介绍
    • ①组播地址
    • ②如何设置组播(组播的使用)
  • 2.代码编写
    • ①服务端
    • ②客户端

1.组播(多播)的介绍

单播地址标识单个 IP 接口,广播地址标识某个子网的所有 IP 接口,多播地址标识一组 IP 接口。单播和广播是寻址方案的两个极端(要么单个要么全部),多播则意在两者之间提供一种折中方案。多播数据报只应该由对它感兴趣的接口接收,也就是说由运行相应多播会话应用系统的主机上的接口接收。另外,广播一般局限于局域网内使用,而多播则既可以用于局域网,也可以跨广域网使用。

  • a: 组播既可以用于局域网,也可以用于广域网
  • b: 客户端需要加入多播组,才能接收到多播的数据

4.34、组播(多播)

①组播地址

IP 多播通信必须依赖于 IP 多播地址,在 IPv4 中它的范围从 224.0.0.0239.255.255.255 ,并被划分为局部链接多播地址、预留多播地址和管理权限多播地址三类:

IP地址 说明
224.0.0.0~224.0.0.255 局部链接多播地址:是为路由协议和其它用途保留的地址,路由器并不转发属于此范围的IP包
224.0.1.0~224.0.1.255 预留多播地址:公用组播地址,可用于Internet;使用前需要申请
224.0.2.0~238.255.255.255 预留多播地址:用户可用组播地址(临时组地址),全网范围内有效
239.0.0.0~239.255.255.255 本地管理组播地址,可供组织内部使用,类似于私有 IP 地址,不能用于 Internet,可限制多播范围

②如何设置组播(组播的使用)

int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);// 服务器设置多播的信息,外出接口- level : IPPROTO_IP- optname : IP_MULTICAST_IF- optval : struct in_addr- // 客户端加入到多播组:- level : IPPROTO_IP- optname : IP_ADD_MEMBERSHIP- optval : struct ip_mreqstruct ip_mreq
{/* IP multicast address of group. */struct in_addr imr_multiaddr; // 组播的IP地址/* Local IP address of interface. */struct in_addr imr_interface; // 本地的IP地址
};typedef uint32_t in_addr_t;
struct in_addr
{in_addr_t s_addr;
};

2.代码编写

①服务端

#include <iostream>
#include <unistd.h>
#include <cstring>
#include <arpa/inet.h>using namespace std;int main() {// 创建通信的fdint fd = socket(PF_INET, SOCK_DGRAM, 0);//设置多播的外出接口in_addr multi_cast;inet_pton(AF_INET, "239.0.0.10", &multi_cast.s_addr);// 设置多播的外出接口setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &multi_cast, sizeof(multi_cast));// 初始化客户端的ip地址和端口sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(9999);inet_pton(AF_INET, "239.0.0.10", &addr.sin_addr.s_addr);int num = 0;char sendBuf[128];while (1) {// 初始化数据sprintf(sendBuf, "hello client, data: %d\\n", num ++ );// 输出数据查看一下cout << sendBuf << endl;// 发送数据sendto(fd, sendBuf, strlen(sendBuf) + 1, 0, (sockaddr *)&addr, sizeof(addr));sleep(1);}return 0;
}

②客户端

#include <iostream>
#include <unistd.h>
#include <cstring>
#include <arpa/inet.h>using namespace std;int main() {// 创建文件描述符int fd = socket(PF_INET, SOCK_DGRAM, 0);// 绑定本地ip和端口sockaddr_in client_addr;client_addr.sin_family = AF_INET;client_addr.sin_port = htons(9999);client_addr.sin_addr.s_addr = INADDR_ANY;bind(fd, (sockaddr *)&client_addr, sizeof(client_addr));// 加入到多播的组中ip_mreq op;inet_pton(AF_INET, "239.0.0.10", &op.imr_multiaddr.s_addr);op.imr_interface.s_addr = INADDR_ANY;setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &op, sizeof(op));char recvBuf[128];while (1) {recvfrom(fd, recvBuf, sizeof(recvBuf), 0, NULL, NULL);cout << "I am client, data: " << recvBuf << endl;}return 0;
}