免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2011 | 回复: 4
打印 上一主题 下一主题

请教一个关于组播的问题:) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-09-15 14:25 |只看该作者 |倒序浏览
工作需要写一段组播的程序,上网下了个例程,编译过后发现几个问题,请高手指点:)

代码如下:
客户端代码

  1. /*
  2. * listen.c - An IP multicast client */
  3. #include <stdio.h>
  4. #include <sys/socket.h>
  5. #include <netinet/in.h>
  6. #include <arpa/inet.h>
  7. #include <netdb.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. char * host_name = "224.0.0.1";
  11. /* 多播IP地址 */
  12. int port = 6789;
  13. int main(void)
  14. {
  15.    struct ip_mreq command;
  16.    int loop = 1;
  17. /* 多播循环 */
  18.   int iter = 0;
  19.   int sin_len;
  20.   char message[256];
  21.   int socket_descriptor;
  22. struct sockaddr_in sin;
  23. struct hostent *server_host_name;
  24. if((server_host_name = gethostbyname(host_name)) == 0)
  25. {
  26.    perror("gethostbyname");
  27.    exit(EXIT_FAILURE);
  28.     }   
  29. /*bzero(&sin, sizeof(sin));*/
  30. memset(&sin, 0, sizeof(sin));
  31.   sin.sin_family = AF_INET;
  32.   sin.sin_addr.s_addr = htonl(INADDR_ANY);
  33.   sin.sin_port = htons(port);
  34.   if((socket_descriptor = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
  35. { perror("socket");
  36. exit(EXIT_FAILURE);
  37. }
  38. /* 调用bind之前,设置套接口选项启用多播IP支持*/
  39. loop = 1;
  40. if(setsockopt(socket_descriptor,
  41. SOL_SOCKET, SO_REUSEADDR,
  42. &loop, sizeof(loop)) < 0)
  43. {
  44. perror("setsockopt:SO_REUSEADDR");
  45. exit(EXIT_FAILURE);
  46.   }
  47. if(bind(socket_descriptor,
  48. (struct sockaddr *)&sin, sizeof(sin)) < 0)
  49. {
  50.    perror("bind");
  51.    exit(EXIT_FAILURE);
  52.     }
  53. /* 在同一个主机上进行广播设置套接口,
  54. 作用是方便单个开发系统上测试多播IP广播 */
  55. loop = 1;
  56. if(setsockopt(socket_descriptor,
  57. IPPROTO_IP, IP_MULTICAST_LOOP,
  58.   &loop, sizeof(loop)) < 0)
  59. {   
  60. perror("setsockopt:IP_MULTICAST_LOOP");
  61. exit(EXIT_FAILURE);
  62.    }
  63. /* 加入一个广播组。进一步告诉Linux内核,
  64. 特定的套接口即将接受广播数据*/
  65. command.imr_multiaddr.s_addr = inet_addr("224.0.0.1");
  66. command.imr_interface.s_addr = htonl(INADDR_ANY);
  67. if(command.imr_multiaddr.s_addr == -1)
  68. {  
  69. perror("224.0.0.1 not a legal multicast address");
  70. exit(EXIT_FAILURE);
  71. }
  72. if (setsockopt(socket_descriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP,
  73.   &command, sizeof(command)) < 0)
  74. {   
  75.   perror("setsockopt:IP_ADD_MEMBERSHIP");
  76.     }
  77. while(iter++ < 8)
  78. {   
  79.   sin_len = sizeof(sin);
  80.   if(recvfrom(socket_descriptor, message, 256, 0,
  81.   (struct sockaddr *)&sin, &sin_len) == -1) {
  82.    perror("recvfrom");   
  83.     }  
  84. printf("Response #%-2d from server: %s\n", iter, message);
  85.      sleep(2);    }
  86.    /* 接受8个广播后退出 */
  87. if(setsockopt(socket_descriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP,
  88.      &command, sizeof(command)) < 0) {
  89.      perror("setsockopt:IP_DROP_MEMBERSHIP");
  90.    }   
  91. close(socket_descriptor);
  92. exit(EXIT_SUCCESS);}

  93. 服务端代码:
  94. /*
  95. * broadcast.c - An IP multicast server
  96. */
  97. #include <stdio.h>
  98. #include <sys/socket.h>
  99. #include <netinet/in.h>
  100. #include <arpa/inet.h>
  101. #include <netdb.h>#include <unistd.h>
  102. #include <stdlib.h>int port = 6789;
  103. int main(void)
  104. {   
  105. int socket_descriptor;  
  106. struct sockaddr_in address;  
  107.   /*  首先建立套接口 */
  108.     socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0);  
  109.   if (socket_descriptor == -1)
  110. {      
  111.   perror("Opening socket");
  112.        exit(EXIT_FAILURE);  
  113.   }   
  114. /* 初始化IP多播地址 */
  115. memset(&address, 0, sizeof(address));   
  116. address.sin_family = AF_INET;  
  117. address.sin_addr.s_addr = inet_addr("224.0.0.1");
  118. address.sin_port = htons(port);  
  119.   /* 开始进行IP多播 */  
  120. while(1) {
  121. if(sendto(socket_descriptor, "test from broadcast",
  122. sizeof("test from broadcast"), 0,   
  123. (struct sockaddr *)&address, sizeof(address)) < 0)
  124. {  
  125. perror("sendto");  
  126. exit(EXIT_FAILURE);
  127. }   
  128. sleep(2);  
  129. }  
  130. exit(EXIT_SUCCESS);}
复制代码


编译过后会出现几个问题:
     第一个  服务器的组地址改变后,比如改成了224.0.1.1,只有本地能受到信息 ,而局网内的另一台pc收不到(他们的组地址也改成224.0.1.1)。
      第二个   服务器的组地址和本地的客户端的组地址不一样,也可以受到信息。

      上述两个问题彻底扰乱了我的思维,请高手指点一下,谢谢:)

[ 本帖最后由 jamesman_xu 于 2007-9-15 17:58 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-09-15 14:26 |只看该作者
天啊,怎么出了几个笑脸 ,晕

论坛徽章:
0
3 [报告]
发表于 2007-09-15 17:05 |只看该作者
原帖由 jamesman_xu 于 2007-9-15 14:26 发表
天啊,怎么出了几个笑脸 ,晕

写代码的时候用[CODE]  [/CODE]即可

论坛徽章:
0
4 [报告]
发表于 2007-09-15 17:59 |只看该作者

回复 #3 maluyao 的帖子

ok! thank u 改过来了 :)

论坛徽章:
0
5 [报告]
发表于 2007-09-17 07:53 |只看该作者
顶一下,高手帮帮忙啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP