UDP 组播 实例

265 篇文章 0 订阅
184 篇文章 2 订阅

http://blog.csdn.net/yanyuanfen2011/article/details/16888801

最近一直在做linux的网络,现在作个总结,陆续贴出来。

在网上搜了很多资料 ,其中周立发的博客对我的学习参考作用最大,谢谢前辈。

直接上代码吧,一个很简单udp 组播通信的例子,分别为服务器端和客户端的代码。


1、服务器端代码 (multi_udp_server.c)

  1. #include <sys/types.h>   
  2. #include <sys/socket.h>   
  3. #include <arpa/inet.h>   
  4. #include <stdio.h>   
  5. #include <stdlib.h>   
  6. #include <string.h>   
  7. #include <netdb.h>   
  8. #include <errno.h>   
  9.   
  10. #define BUFLEN 255   
  11. /********************************************************************* 
  12. *filename: mcastserver.c 
  13. *purpose: 演示组播编程的基本步骤,组播服务器端,关键在于加入组 
  14. *tidied by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com) 
  15. Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言 
  16. *date time:2007-01-25 13:20:00 
  17. *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途 
  18. * 但请遵循GPL 
  19. *Thanks to: Google.com 
  20. *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力 
  21. * 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献! 
  22. *********************************************************************/  
  23. int main(int argc, charchar **argv)  
  24. {  
  25. struct sockaddr_in peeraddr;  
  26. struct in_addr ia;  
  27. int sockfd;  
  28. char recmsg[BUFLEN + 1];  
  29. unsigned int socklen, n;  
  30. struct hostent *group;  
  31. struct ip_mreq mreq;  
  32.   
  33. /* 创建 socket 用于UDP通讯 */  
  34. sockfd = socket(AF_INET, SOCK_DGRAM, 0);  
  35. if (sockfd < 0) {  
  36. printf("socket creating err in udptalk\n");  
  37. exit(1);  
  38. }  
  39.   
  40. /* 设置要加入组播的地址 */  
  41. bzero(&mreq, sizeof(struct ip_mreq));  
  42. if (argv[1]) {  
  43.     if ((group = gethostbyname(argv[1])) == (struct hostent *) 0) {  
  44.         perror("gethostbyname");  
  45.         exit(errno);  
  46.     }  
  47. else {  
  48.     printf  
  49.         ("you should give me a group address, 224.0.0.0-239.255.255.255\n");  
  50.     exit(errno);  
  51. }  
  52.   
  53. bcopy((voidvoid *) group->h_addr, (voidvoid *) &ia, group->h_length);  
  54. /* 设置组地址 */  
  55. bcopy(&ia, &mreq.imr_multiaddr.s_addrsizeof(struct in_addr));  
  56.   
  57. /* 设置发送组播消息的源主机的地址信息 */  
  58. mreq.imr_interface.s_addr = htonl(INADDR_ANY);  
  59.   
  60. /* 把本机加入组播地址,即本机网卡作为组播成员,只有加入组才能收到组播消息 */  
  61. if (setsockopt  
  62.         (sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,  
  63.          sizeof(struct ip_mreq)) == -1) {  
  64.     perror("setsockopt");  
  65.     exit(-1);  
  66. }  
  67.   
  68. socklen = sizeof(struct sockaddr_in);  
  69. memset(&peeraddr, 0, socklen);  
  70. peeraddr.sin_family = AF_INET;  
  71. if (argv[2])  
  72.     peeraddr.sin_port = htons(atoi(argv[2]));  
  73.     else  
  74.     peeraddr.sin_port = htons(7838);  
  75.     if (argv[1]) {  
  76.         if (inet_pton(AF_INET, argv[1], &peeraddr.sin_addr) <= 0) {  
  77.             printf("Wrong dest IP address!\n");  
  78.             exit(0);  
  79.         }  
  80.     } else {  
  81.         printf("no group address given, 224.0.0.0-239.255.255.255\n");  
  82.         exit(errno);  
  83.     }  
  84.   
  85. /* 绑定自己的端口和IP信息到socket上 */  
  86. if (bind  
  87.         (sockfd, (struct sockaddr *) &peeraddr,  
  88.          sizeof(struct sockaddr_in)) == -1) {  
  89.     printf("Bind error\n");  
  90.     exit(0);  
  91. }  
  92.   
  93. /* 循环接收网络上来的组播消息 */  
  94. for (;;) {  
  95.     bzero(recmsg, BUFLEN + 1);  
  96.     n = recvfrom(sockfd, recmsg, BUFLEN, 0,  
  97.             (struct sockaddr *) &peeraddr, &socklen);  
  98.     if (n < 0) {  
  99.         printf("recvfrom err in udptalk!\n");  
  100.         exit(4);  
  101.     } else {  
  102.         /* 成功接收到数据报 */  
  103.         recmsg[n] = 0;  
  104.         printf("peer:%s", recmsg);  
  105.     }  
  106. }  
  107. }  
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <errno.h>

#define BUFLEN 255
/*********************************************************************
*filename: mcastserver.c
*purpose: 演示组播编程的基本步骤,组播服务器端,关键在于加入组
*tidied by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
*date time:2007-01-25 13:20:00
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循GPL
*Thanks to: Google.com
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*********************************************************************/
int main(int argc, char **argv)
{
struct sockaddr_in peeraddr;
struct in_addr ia;
int sockfd;
char recmsg[BUFLEN + 1];
unsigned int socklen, n;
struct hostent *group;
struct ip_mreq mreq;

/* 创建 socket 用于UDP通讯 */
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
printf("socket creating err in udptalk\n");
exit(1);
}

/* 设置要加入组播的地址 */
bzero(&mreq, sizeof(struct ip_mreq));
if (argv[1]) {
	if ((group = gethostbyname(argv[1])) == (struct hostent *) 0) {
		perror("gethostbyname");
		exit(errno);
	}
} else {
	printf
		("you should give me a group address, 224.0.0.0-239.255.255.255\n");
	exit(errno);
}

bcopy((void *) group->h_addr, (void *) &ia, group->h_length);
/* 设置组地址 */
bcopy(&ia, &mreq.imr_multiaddr.s_addr, sizeof(struct in_addr));

/* 设置发送组播消息的源主机的地址信息 */
mreq.imr_interface.s_addr = htonl(INADDR_ANY);

/* 把本机加入组播地址,即本机网卡作为组播成员,只有加入组才能收到组播消息 */
if (setsockopt
		(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
		 sizeof(struct ip_mreq)) == -1) {
	perror("setsockopt");
	exit(-1);
}

socklen = sizeof(struct sockaddr_in);
memset(&peeraddr, 0, socklen);
peeraddr.sin_family = AF_INET;
if (argv[2])
	peeraddr.sin_port = htons(atoi(argv[2]));
	else
	peeraddr.sin_port = htons(7838);
	if (argv[1]) {
		if (inet_pton(AF_INET, argv[1], &peeraddr.sin_addr) <= 0) {
			printf("Wrong dest IP address!\n");
			exit(0);
		}
	} else {
		printf("no group address given, 224.0.0.0-239.255.255.255\n");
		exit(errno);
	}

/* 绑定自己的端口和IP信息到socket上 */
if (bind
		(sockfd, (struct sockaddr *) &peeraddr,
		 sizeof(struct sockaddr_in)) == -1) {
	printf("Bind error\n");
	exit(0);
}

/* 循环接收网络上来的组播消息 */
for (;;) {
	bzero(recmsg, BUFLEN + 1);
	n = recvfrom(sockfd, recmsg, BUFLEN, 0,
			(struct sockaddr *) &peeraddr, &socklen);
	if (n < 0) {
		printf("recvfrom err in udptalk!\n");
		exit(4);
	} else {
		/* 成功接收到数据报 */
		recmsg[n] = 0;
		printf("peer:%s", recmsg);
	}
}
}

文件编译:gcc -Wall multi_udp_server.c -o server 

运行:./server 230.1.1.1 7838


2、客户端代码(multi_udp_clinet.c)

  1. #include <sys/types.h>   
  2. #include <sys/socket.h>   
  3. #include <arpa/inet.h>   
  4. #include <stdio.h>   
  5. #include <stdlib.h>   
  6. #include <string.h>   
  7.   
  8. #define BUFLEN 255   
  9. /********************************************************************* 
  10.  *filename: mcastclient.c 
  11.  *purpose: 演示组播编程的基本步骤,其实这就是一个基本的UDP客户端程序 
  12.  *tidied by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com) 
  13.  Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言 
  14.  *date time:2007-01-25 13:10:00 
  15.  *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途 
  16.  * 但请遵循GPL 
  17.  *Thanks to: Google.com 
  18.  *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力 
  19.  * 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献! 
  20.  *********************************************************************/  
  21. int main(int argc, charchar **argv)  
  22. {  
  23.     struct sockaddr_in peeraddr, myaddr;  
  24.   
  25.     int sockfd;  
  26.     char recmsg[BUFLEN + 1];  
  27.     unsigned int socklen;  
  28.   
  29.     /* 创建 socket 用于UDP通讯 */  
  30.     sockfd = socket(AF_INET, SOCK_DGRAM, 0);  
  31.     if (sockfd < 0) {  
  32.         printf("socket creating error\n");  
  33.         exit(1);  
  34.     }  
  35.     socklen = sizeof(struct sockaddr_in);  
  36.   
  37.     /* 设置对方的端口和IP信息 */  
  38.     memset(&peeraddr, 0, socklen);  
  39.     peeraddr.sin_family = AF_INET;  
  40.     if (argv[2])  
  41.         peeraddr.sin_port = htons(atoi(argv[2]));  
  42.     else  
  43.         peeraddr.sin_port = htons(7838);  
  44.     if (argv[1]) {  
  45.         /* 注意这里设置的对方地址是指组播地址,而不是对方的实际IP地址 */  
  46.         if (inet_pton(AF_INET, argv[1], &peeraddr.sin_addr) <= 0) {  
  47.             printf("wrong group address!\n");  
  48.             exit(0);  
  49.         }  
  50.     } else {  
  51.         printf("no group address!\n");  
  52.         exit(0);  
  53.     }  
  54.   
  55.     /* 设置自己的端口和IP信息 */  
  56.     memset(&myaddr, 0, socklen);  
  57.     myaddr.sin_family = AF_INET;  
  58.     if (argv[4])  
  59.         myaddr.sin_port = htons(atoi(argv[4]));  
  60.     else  
  61.         myaddr.sin_port = htons(23456);  
  62.   
  63.     if (argv[3]) {  
  64.         if (inet_pton(AF_INET, argv[3], &myaddr.sin_addr) <= 0) {  
  65.             printf("self ip address error!\n");  
  66.             exit(0);  
  67.         }  
  68.     } else  
  69.         myaddr.sin_addr.s_addr = INADDR_ANY;  
  70.   
  71.     /* 绑定自己的端口和IP信息到socket上 */  
  72.     if (bind  
  73.             (sockfd, (struct sockaddr *) &myaddr,  
  74.              sizeof(struct sockaddr_in)) == -1) {  
  75.         printf("Bind error\n");  
  76.         exit(0);  
  77.     }  
  78.   
  79.     /* 循环接受用户输入的消息发送组播消息 */  
  80.     for (;;) {  
  81.         /* 接受用户输入 */  
  82.         bzero(recmsg, BUFLEN + 1);  
  83.         if (fgets(recmsg, BUFLEN, stdin) == (charchar *) EOF)  
  84.             exit(0);  
  85.         /* 发送消息 */  
  86.         if (sendto  
  87.                 (sockfd, recmsg, strlen(recmsg), 0,  
  88.                  (struct sockaddr *) &peeraddr,  
  89.                  sizeof(struct sockaddr_in)) < 0) {  
  90.             printf("sendto error!\n");  
  91.             exit(3);  
  92.         }  
  93.         printf("'%s' send ok\n", recmsg);  
  94.     }  
  95. }  
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFLEN 255
/*********************************************************************
 *filename: mcastclient.c
 *purpose: 演示组播编程的基本步骤,其实这就是一个基本的UDP客户端程序
 *tidied by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
 Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
 *date time:2007-01-25 13:10:00
 *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
 * 但请遵循GPL
 *Thanks to: Google.com
 *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
 * 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
 *********************************************************************/
int main(int argc, char **argv)
{
	struct sockaddr_in peeraddr, myaddr;

	int sockfd;
	char recmsg[BUFLEN + 1];
	unsigned int socklen;

	/* 创建 socket 用于UDP通讯 */
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sockfd < 0) {
		printf("socket creating error\n");
		exit(1);
	}
	socklen = sizeof(struct sockaddr_in);

	/* 设置对方的端口和IP信息 */
	memset(&peeraddr, 0, socklen);
	peeraddr.sin_family = AF_INET;
	if (argv[2])
		peeraddr.sin_port = htons(atoi(argv[2]));
	else
		peeraddr.sin_port = htons(7838);
	if (argv[1]) {
		/* 注意这里设置的对方地址是指组播地址,而不是对方的实际IP地址 */
		if (inet_pton(AF_INET, argv[1], &peeraddr.sin_addr) <= 0) {
			printf("wrong group address!\n");
			exit(0);
		}
	} else {
		printf("no group address!\n");
		exit(0);
	}

	/* 设置自己的端口和IP信息 */
	memset(&myaddr, 0, socklen);
	myaddr.sin_family = AF_INET;
	if (argv[4])
		myaddr.sin_port = htons(atoi(argv[4]));
	else
		myaddr.sin_port = htons(23456);

	if (argv[3]) {
		if (inet_pton(AF_INET, argv[3], &myaddr.sin_addr) <= 0) {
			printf("self ip address error!\n");
			exit(0);
		}
	} else
		myaddr.sin_addr.s_addr = INADDR_ANY;

	/* 绑定自己的端口和IP信息到socket上 */
	if (bind
			(sockfd, (struct sockaddr *) &myaddr,
			 sizeof(struct sockaddr_in)) == -1) {
		printf("Bind error\n");
		exit(0);
	}

	/* 循环接受用户输入的消息发送组播消息 */
	for (;;) {
		/* 接受用户输入 */
		bzero(recmsg, BUFLEN + 1);
		if (fgets(recmsg, BUFLEN, stdin) == (char *) EOF)
			exit(0);
		/* 发送消息 */
		if (sendto
				(sockfd, recmsg, strlen(recmsg), 0,
				 (struct sockaddr *) &peeraddr,
				 sizeof(struct sockaddr_in)) < 0) {
			printf("sendto error!\n");
			exit(3);
		}
		printf("'%s' send ok\n", recmsg);
	}
}

编译:gcc -Wall multi_udp_clinet.c -o clinet

运行:./clinet 230.1.1.1 7838 192.168.1.121 5500


运行结果图如下:



只要在客户端,敲入要发的字符,就可以服务器端看到了。


linux网络编程源代码下载:http://download.csdn.net/detail/yanyuanfen2011/6595113


如有问题欢迎留言交流!

 

  • 4
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值