Chinaunix首页 | 论坛 | 博客
  • 博客访问: 245622
  • 博文数量: 34
  • 博客积分: 791
  • 博客等级: 军士长
  • 技术积分: 352
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-24 21:45
文章分类

全部博文(34)

文章存档

2015年(2)

2013年(6)

2012年(16)

2011年(8)

2010年(2)

分类: LINUX

2011-12-24 15:55:42

Multicast Sockets - Programming Tips

Here are a few tips on working with multicast sockets and UNIX (FreeBSD).

  1. Sending socket. In general, there's nothing special you need to do on the sending end. The key is simply to send to a multicast IP (group) address. Tips:
    • Use socket() with AF_INET and SOCK_DGRAM arguments as normal.
    • Use bind() to associate this socket with a local address and port.
    • Do not attempt to associate the socket with a multicast destination address using connect().
    • Use sendto() for sending data.
  2. Receiving socket. Receiving is nearly the same, but with one additional system call: setsockopt().
    • Use socket() with AF_INET and SOCK_DGRAM arguments as normal.
    • Use setsockopt() with the IP_ADD_MEMBERSHIP option. This tells the system to receive packets on the network whose destination is the group address (but not its own). Here's an example in C++: struct sockaddr_in sockaddr_group;
      struct hostent *group;
      struct ip_mreq mreq;

      bzero(&mreq,sizeof(struct ip_mreq));

      // set group

      if ((group = gethostbyname(ghost))==(struct hostent *)0) {
      cerr << "gethostbyname error: fails for host " << host << endl;
      exit(-1);
      }

      struct in_addr ia;
      bcopy((void*)group->h_addr,
      (void*)&ia,
      group->h_length);
      bcopy(&ia,
      &mreq.imr_multiaddr.s_addr,
      sizeof(struct in_addr));

      // set interface

      mreq.imr_interface.s_addr = htonl(INADDR_ANY);

      // do membership call

      if (setsockopt(sockfd,
      IPPROTO_IP,
      IP_ADD_MEMBERSHIP,
      &mreq,
      sizeof(struct ip_mreq))
      == -1) {
      cerr << "error: setsockopt(IP_ADD_MEMBERSHIP) fails with errno "
      << errno << endl;
      exit(-1);
      }
    • Use bind() to associate this socket with a local address and port.
    • Do not attempt to associate the socket with a multicast destination address using connect().
    • Use recvfrom() for receiving data.
  3. Other multicast socket options. A list of additional options is below. IP_MULTICAST_IF /* u_char; set/get IP multicast i/f */
    IP_MULTICAST_TTL /* u_char; set/get IP multicast ttl */
    IP_MULTICAST_LOOP /* u_char; set/get IP multicast loopback */
    IP_ADD_MEMBERSHIP /* ip_mreq; add an IP group membership */
    IP_DROP_MEMBERSHIP /* ip_mreq; drop an IP group membership */

    Use IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP to switch multicast groups "listened" for by the recieving socket. Use IP_MULTICAST_LOOP if you would like the sender to also receive a copy of what is sent to the group. I don't believe IP_MULTICAST_IF or IP_MULTICAST_TTL will be of interest for what we're doing.

  4. Further reading.
    • See the following include file for type definitions: /usr/include/netinet/in.h
    • For more about multicast socket programming, try UNIX Network Programming, Second Edition, by W. Richard Stevens (Prentice Hall, 1998). In particular, see Chapter 19 on "Multicasting".


阅读(1396) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~