我发现网上关于组播的例子不多,而且有的在我所用的系统上还有问题,所以把我自己写的简单例子记录一下。前面有两篇关于组播的博客,这是连续的第三篇,就当作一个系列吧。。。
服务端(接收端)
#include "../common/common.h"
#include <netdb.h>
#define MAXLINE 1024
int main(int argc, char *argv[])
{
if (argc != 4)
{
printf("usage: %s ip port multicast\n", argv[0]);
exit(EXIT_FAILURE);
}
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(atoi(argv[2]));
bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
struct ip_mreq ipmr;
inet_pton(AF_INET, argv[1], &ipmr.imr_interface);
inet_pton(AF_INET, argv[3], &ipmr.imr_multiaddr);
if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &ipmr, sizeof(ipmr)) < 0)
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
char recvline[MAXLINE];
char buf[64];
while (1)
{
sockaddr_in cliaddr;
socklen_t len = sizeof(cliaddr);
int n = recvfrom(sockfd, recvline, MAXLINE, 0, (struct sockaddr *)&cliaddr, &len);
if (n < 0)
{
perror("recvfrom");
exit(EXIT_FAILURE);
}
printf("recv %s from %s:%d\n", recvline,
inet_ntop(AF_INET, &cliaddr.sin_addr, buf, sizeof(buf)) ,cliaddr.sin_port);
}
}
客户端(发送端)
#include "../common/common.h"
#define MAXLINE 1024
void dg_cli(FILE *fp, int sockfd, const struct sockaddr *pservaddr, socklen_t servlen)
{
char sendline[MAXLINE];
while (fgets(sendline, MAXLINE, fp) != NULL)
{
size_t len = strlen(sendline);
if (sendto(sockfd, sendline, len, 0, pservaddr, servlen) != (ssize_t)len)
{
perror("sendto");
exit(EXIT_FAILURE);
}
}
}
int main(int argc, char *argv[])
{
if (argc != 4)
{
printf("%s ip port multicast\n", argv[0]);
exit(EXIT_FAILURE);
}
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
perror("sockfd");
exit(EXIT_FAILURE);
}
u_char loopback = 1;
if (setsockopt (sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loopback, sizeof(loopback)) < 0)
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
struct sockaddr_in cliaddr;
cliaddr.sin_family = AF_INET;
cliaddr.sin_port = 0;
if (inet_pton(AF_INET, argv[1], &cliaddr.sin_addr) != 1)
{
printf("inet_pton fail\n");
exit(EXIT_FAILURE);
}
if (bind(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr)) < 0)
{
perror("bind");
exit(EXIT_FAILURE);
}
struct sockaddr_in seraddr;
memset(&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(atoi(argv[2]));
if (inet_pton(AF_INET, argv[3], &seraddr.sin_addr) != 1)
{
printf("inet_pton fail\n");
exit(EXIT_FAILURE);
}
dg_cli(stdin, sockfd, (struct sockaddr*)&seraddr, sizeof(seraddr));
exit(EXIT_SUCCESS);
}
使用方法:这两个程序都需要三个参数,第一个参数是本机的IP,第二个参数是使用的服务端端口号,第三个参数是组播IP。
不过头文件要自己加,懒得写了。。。