一个简单的Linux下组播通信的例子

 
发送端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <errno.h>
#include <netinet/in.h>

#define PORTNUM 5000
#define GROUPIP "224.0.1.1"

int main()
{
int sock_id;
struct sockaddr_in addr;
char buf[] = "This is a test message.";
socklen_t len;
int ret;

/* open a socket. only udp support multicast */
if ((sock_id = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket error");
exit(1);
}

/* build address */
memset((void*)&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(GROUPIP); /* multicast group ip */
addr.sin_port = htons(PORTNUM);

len = sizeof(addr);
while (1) {
/* it's very easy, just send the data to the address:port */
ret = sendto(sock_id, buf, strlen(buf), 0,
(struct sockaddr *)&addr, len);
if (ret < 0) {
perror("sendto error");
exit(1);
}
printf("Send to %s:%u\n",
inet_ntoa(addr.sin_addr.s_addr), ntohs(addr.sin_port));
sleep(2); /* wait 2 sec. */
}

close(sock_id);

return 0;
}


接收端

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <errno.h>
#include <netinet/in.h>

#define PORTNUM 5000
#define GROUPIP "224.0.1.1"
#define BUFLEN 1024
#define TESTNUM 10

int main()
{
int sock_id;
struct sockaddr_in addr, sender;
struct ip_mreq ipmr;
char buf[BUFLEN];
socklen_t len;
int ret;
int count;

/* Step 1: open a socket, and bind */
if ((sock_id = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket error");
exit(1);
}

memset((void*)&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(PORTNUM);

if (bind(sock_id, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind error");
exit(1);
}

/* Step 2: fill in a struct ip_mreq */
memset((void*)&ipmr, 0, sizeof(ipmr));
ipmr.imr_multiaddr.s_addr = inet_addr(GROUPIP); /* multicast group ip */
ipmr.imr_interface.s_addr = htonl(INADDR_ANY);

/* Step 3: call setsockopt with IP_ADD_MEMBERSHIP to support receiving multicast */
if (setsockopt(sock_id, IPPROTO_IP, IP_ADD_MEMBERSHIP, &ipmr, sizeof(ipmr)) < 0) {
perror("setsockopt:IP_ADD_MEMBERSHIP");
exit(1);
}

/* Step 4: call recvfrom to receive multicast packets */
len = sizeof(sender);
count = 0;
while (count < TESTNUM) {
ret = recvfrom(sock_id, buf, BUFLEN, 0, (struct sockaddr *)&sender, &len);
buf[ret] = '\0';
if (ret < 0) {
perror("recvfrom error");
exit(1);
}
printf("%d. Receive from %s:%u\n", count,
inet_ntoa(sender.sin_addr.s_addr), ntohs(sender.sin_port));
printf("\tpacket data: %s\n", buf);
}

/* Step 5: call setsockopt with IP_DROP_MEMBERSHIP to drop from multicast */
if (setsockopt(sock_id, IPPROTO_IP, IP_DROP_MEMBERSHIP, &ipmr, sizeof(ipmr)) < 0) {
perror("setsockopt:IP_DROP_MEMBERSHIP");
exit(1);
}

/* Step 6: close the socket */
close(sock_id);

return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值