UDP组播接收端的绑定问题bind(),IP_ADD_MEMBERSHIP

15 篇文章 1 订阅

UDP组播接收的代码如下:

struct sockaddr_in    localSock;
struct ip_mreq        group;
int                   sd;
int                   datalen;
char                  databuf[1024];

int main (int argc, char *argv[])
{
  sd = socket(AF_INET, SOCK_DGRAM, 0);
  if (sd < 0) {
    perror("opening datagram socket");
    exit(1);
  }
  
  memset((char *) &localSock, 0, sizeof(localSock));
  localSock.sin_family = AF_INET;
  localSock.sin_port = htons(5555);;
  localSock.sin_addr.s_addr  = INADDR_ANY; // or mcast_ip
  if (bind(sd, (struct sockaddr*)&localSock, sizeof(localSock))) {
    perror("binding datagram socket");
    close(sd);
    exit(1);
  }

  group.imr_multiaddr.s_addr = inet_addr("225.1.1.1"); //mcast_ip
  group.imr_interface.s_addr = inet_addr("9.5.1.1"); //local_ip
  if (setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                 (char *)&group, sizeof(group)) < 0) {
    perror("adding multicast group");
    close(sd);
    exit(1);
  }
  
  datalen = sizeof(databuf);
  if (read(sd, databuf, datalen) < 0) {
    perror("reading datagram message");
    close(sd);
    exit(1);
  }
}

socket有两个操作,一个是bind, 一个是setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP,…)。

  1. bind()

TCP中bind()的意思是将该socket绑定到某个IP:PORT上,组播的意思是socket只接收该组播组的数据包。

如果这里绑定的是INADDR_ANY, 这个socket就讲接收到能听到的所有组播组IP相同端口的数据包, 即组播IP不同,端口相同时,组播串线的情况。

如果这里绑定的是某个具体组播组的IP, 这里内核向socket发送数据的时候就会过滤掉不是该组播组的数据。

据说在Windows中应该绑定物理网卡的IP地址, 而不是组播地址。

  1. IP_ADD_MEMBERSHIP

IP_ADD_MEMBERSHIP意思是加入组播组。 根据IGMP协议,主机将会向组播管理端发送一个报文,报告本机要加入某个交换机,交换机就会向相应的端口转发这个组播组的数据包。 group.imr_multiaddr.s_addr为组播组IP。
group.imr_interface.s_addr一般写要加入组播组主机的接口/网卡的 IP, 以确定收取哪一个子网的组播信息,会通过该接口接收组播包。如果设为INADDR_ANY(0.0.0.0),则使用默认的IPV4组播接口。
route -n 可以显示默认组播路由。

只有交换机的某个端口有对应组播组的接收host加入过组播组, 交换机才会向该端口组播数据包,否则默认是不不组播的。

补充:
IP_ADD_SOURCE_MEMBERSHIP可以指定组播源的IP, 即source_ip.
IP_MULTICAST_IF 可以设置组播发送端口

Ref:
https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_71/rzab6/x2multicast.htm

  • 0
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VxWorks是一个支持多种通信协议的实时操作系统,其中包括UDP协议。组播是一种UDP协议的实现方式,其可以使多个应用程序同时接收同一组数据,并且可以在网络上跨越多个子网。 在VxWorks系统中,UDP组播接收的实现方法如下: 1. 创建UDP套接字。可以使用socket()系统调用创建一个UDP套接字。例如,可以通过以下语句创建一个UDP套接字: int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 2. 将套接字绑定组播地址上。可以使用bind()系统调用将UDP套接字绑定组播地址上。例如,可以使用以下语句将套接字绑定组播地址上: struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port_no); addr.sin_addr.s_addr = INADDR_ANY; bind(sock, (struct sockaddr*)&addr, sizeof(addr)); 3. 加入组播组。可以使用setsockopt()系统调用将UDP套接字加入到指定的组播组中。例如,可以使用以下语句将套接字加入到组播组中: struct ip_mreq mreq; memset(&mreq, 0, sizeof(mreq)); mreq.imr_interface.s_addr = htonl(INADDR_ANY); mreq.imr_multiaddr.s_addr = inet_addr(multicast_group); setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq)); 4. 接收组播数据。可以使用recvfrom()系统调用从UDP套接字接收组播数据。例如,可以使用以下语句从套接字接收组播数据: char buf[BUFFER_SIZE]; memset(buf, 0, sizeof(buf)); recvfrom(sock, buf, BUFFER_SIZE, 0, (struct sockaddr*)&addr, &addrlen); 在完成UDP组播接收后,应使用close()系统调用关闭UDP套接字以释放系统资源。例如,可以使用以下语句关闭套接字: close(sock); 总之,以上就是VxWorks系统中UDP组播接收的实现方法。通过以上步骤,我们就可以在VxWorks系统中实现UDP组播接收,并且可以高效地传输数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值