107-使用多播的 UDP C/S 程序

来源:互联网 发布:公务员备考资料知乎 编辑:程序博客网 时间:2024/06/07 05:12

在掌握了多播的相关基础后,本文我们通过实例来演示如何让你的进程加入多播组。

1. 程序路径

本文使用的程序托管在 gitos 上:http://git.oschina.net/ivan_allen/unp

本文使用的程序路径为 unp/program/multicast/basic.

2. 客户端

udp 客户端部分无需做任何更改,在指定目标 ip 地址的时候,直接使用多播地址。意思是说,向这个“QQ群”发信息。

3. 服务器

udp 服务器相对于之前的区别就是加入一个多播组,所以这里关键是如何加入多播组的问题。下面是具体程序,关键的地方已做注释。

void server_routine() {  int ret, sockfd;  struct sockaddr_in servaddr, cliaddr;  socklen_t cliaddrlen;  // 加入多播组要填充的结构体  struct ip_mreq mreq;  ret = resolve(g_option.hostname, g_option.port, &servaddr);  if (ret < 0) ERR_EXIT("resolve");  sockfd = socket(AF_INET, SOCK_DGRAM, 0);  if (sockfd < 0) ERR_EXIT("socket");  // 绑定本地接口,默认为 INADDR_ANY  ret = bind(sockfd, (struct sockaddr*)&servaddr, sizeof servaddr);  if (ret < 0) ERR_EXIT("bind");  // “构造QQ群号”:填充要加入的多播组地址,比如 230.2.2.2  mreq.imr_multiaddr.s_addr = inet_addr(g_option.multiAddr);  // “指定要加入QQ群的QQ号”:指定哪个接口(网卡出口)加入多播组  mreq.imr_interface.s_addr = servaddr.sin_addr.s_addr;  // “加入QQ群”:调用 setsockopt 函数,将网卡出口加入指定的多播组  ret = setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));  if (ret < 0) ERR_EXIT("setsockopt:IP_ADD_MEMBERSHIP");  LOG("multicast group: %s\n", g_option.multiAddr);  doServer(sockfd);  // “退群”:将网卡接口移出多播组  ret = setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));  if (ret < 0) ERR_EXIT("setsockopt:IP_DROP_MEMBERSHIP");  close(sockfd);}

上面的程序非常简单,一旦有多个服务器加入了同一个多播组,客户端向此多播组发送信息,所有的服务器都能收到信息。

4. 相关的套接字选项(IPv4)

再看完第 3 小节的程序后,有必要对相关的套接字选项做介绍。Linux/Unix 提供了很多套接字选项用来操作多播。

表1 组成员无关多播套接字选项

选项名 数据类型 说明 IP_MULTICAST_IF struct in_addr 发送多播数据报时,指定外出接口 IP_MULTICAST_TTL u_char 指定外出多播数据报的 TTL IP_MULTICAST_LOOP u_char 开启或禁止外出多播数据报回环

表2 组成员相关多播套接字选项

选项名 数据类型 说明 IP_ADD_MEMBERSHIP struct ip_mreq 加入一个多播组 IP_DROP_MEMBERSHIP struct ip_mreq 离开一个多播组

表 1 和表 2 只列举了一部分,还有一些,暂时不例举。上面列举的,都是我们目前能看懂的。在第 3 节的例子中,已经演示了 IP_ADD_MEMBERSHIP 和 IP_DROP_MEMBERSHIP 的用法。

5. 实验

在 flower 主机和 moon 主机上启动两个 UDP 多播服务器,多播地址是230.2.2.2,端口号是 7777,然后在 moon 主机上启动 UDP 客户端,向组 230.2.2.2 发信息。

  • 启动 udp 服务器
// 默认组地址是 230.2.2.2,所以 -g 选项可以不用写$ ./mc -s -p 7777 -g 230.2.2.2
  • 启动客户端
$ ./mc -h 230.2.2.2
  • 运行结果


这里写图片描述
图1 客户端


这里写图片描述
图2 moon 主机上的服务器


这里写图片描述
图3 flower 主机上的服务器

6 总结

  • 掌握如何加入一个组
原创粉丝点击