Skip to content
On this page

组播接收端代码


标签:代码片段C/unix  

Code:hqyj/network/04/grouprec.c

c
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define ERR_MSG(msg)                                                           \
  do {                                                                         \
    fprintf(stderr, "line %d\n", __LINE__);                                    \
    perror(msg);                                                               \
  } while (0)

#define PORT 2222
#define GRP_IP "224.1.2.3"
#define LOCAL_IP "192.168.31.125"

int main(int argc, char const *argv[]) {
  // 创建报式套接字
  int sfd = socket(AF_INET, SOCK_DGRAM, 0);
  if (sfd < 0) {
    ERR_MSG("socket");
    return -1;
  }
  printf("socket create success sfd=%d __%d__\n",
         sfd, __LINE__);

  // 加入多播组
  struct ip_mreqn mq;
  /* 指定要加入的组播IP,与下面bind时候填充的一致 */
  mq.imr_multiaddr.s_addr =
      inet_addr(GRP_IP);
  mq.imr_address.s_addr = inet_addr(LOCAL_IP); /* 本机IP */
  /* 网卡设备索引号 */
  mq.imr_ifindex = if_nametoindex("ens33");

  if (setsockopt(sfd, IPPROTO_IP,
                 IP_ADD_MEMBERSHIP, &mq, sizeof(mq)) < 0) {
    ERR_MSG("setsockopt");
    return -1;
  }
  printf("加入 %s 多播组成功\n", GRP_IP);

  // 填充服务器的地址信息结构体,绑定到套接字上
  struct sockaddr_in sin;
  sin.sin_family = AF_INET;
  sin.sin_port = htons(PORT);              // 1024~49151
  sin.sin_addr.s_addr = inet_addr(GRP_IP);

  // 绑定 -- 必须绑定
  if (bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
    ERR_MSG("bind");
    return -1;
  }
  printf("bind success __%d__\n", __LINE__);

  char buf[128] = "";
  ssize_t res = 0;

  struct sockaddr_in cin;
  socklen_t addrlen = sizeof(cin);

  while (1) {
    bzero(buf, sizeof(buf));
    // 接收数据
    res = recvfrom(sfd, buf, sizeof(buf), 0,
                   (struct sockaddr *)&cin, &addrlen);
    if (res < 0) {
      ERR_MSG("recvfrom");
      return -1;
    }
    printf("[%s : %d]: %s\n",
           inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),
           buf);
  }
  // 关闭套接字
  close(sfd);
  return 0;
}

Last updated: