Linux下UDP的组播接收和发送的简单例子

  1. /* 发送端 */  
  2. #include <sys/types.h>  
  3. #include <sys/socket.h>  
  4. #include <sys/ioctl.h>  
  5. #include <netinet/in.h>  
  6. #include <arpa/inet.h>  
  7. #include <time.h>  
  8. #include <string.h>  
  9. #include <stdio.h>  
  10. #include <unistd.h>  
  11. #include <stdlib.h>  
  12. #include <net/if.h>  
  13.   
  14. #define TRAM_STATUS_ADDR 239.0.0.30  
  15. #define TRAM_STATUS_RECV_PORT 9200  
  16.   
  17. int main(int argc, char **argv)  
  18. {  
  19.       
  20.     struct sockaddr_in addr, mcast_addr;  
  21.     int fd, cnt;  
  22.     struct ip_mreq mreq;  
  23.     int addrlen, num;  
  24.     char msg[32];  
  25.       
  26.     sprintf(msg, "%s", "hello");  
  27.   
  28.     if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)  
  29.     {  
  30.         perror("socket");  
  31.         return -1;  
  32.     }  
  33.   
  34.     memset(&mcast_addr, 0, sizeof(mcast_addr));  
  35.     mcast_addr.sin_family = AF_INET;  
  36.     mcast_addr.sin_addr.s_addr = inet_addr(TRAM_STATUS_ADDR);  
  37.     mcast_addr.sin_port = htons(TRAM_STATUS_RECV_PORT);          
  38.   
  39.     if (sendto(fd, (const char *)msg, sizeof(msg), 0, (struct sockaddr *)&mcast_addr, sizeof(mcast_addr)) < 0)  
  40.     {  
  41.         perror("sendto");  
  42.         return -1;  
  43.     }  
  44.     printf("send ok!\n");  
  45.   
  46.     setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mcast_addr, sizeof(mcast_addr));  
  47.     close(fd);  
  48.       
  49.     return 0;  
  50. }  
  51.   
  52. /* 接收端 */  
  53. #include <sys/types.h>  
  54. #include <sys/socket.h>  
  55. #include <netinet/in.h>  
  56. #include <arpa/inet.h>  
  57. #include <time.h>  
  58. #include <string.h>  
  59. #include <stdio.h>  
  60. #include <unistd.h>  
  61. #include <stdlib.h>  
  62. #include <sys/ioctl.h>  
  63.   
  64. #define MSGBUFSIZE 256  
  65. #define TRAM_STATUS_ADDR 239.0.0.30  
  66. #define TRAM_STATUS_RECV_PORT 9200  
  67.   
  68. int main()  
  69. {  
  70.     struct sockaddr_in addr;  
  71.     int fd, nbytes, addrlen;  
  72.     struct ip_mreq mreq;  
  73.     char msgbuf[MSGBUFSIZE];  
  74.     int on;  
  75.       
  76.     if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)  
  77.     {  
  78.         perror("socket ");  
  79.         return -1;  
  80.     }  
  81.     /* 初始化地址 */  
  82.     memset(&addr, 0, sizeof(addr));  
  83.     addr.sin_family = AF_INET;  
  84.     addr.sin_addr.s_addr = htonl(INADDR_ANY);  
  85.     addr.sin_port = htons(TRAM_STATUS_RECV_PORT);  
  86.   
  87.     if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)  
  88.     {  
  89.         perror("bind");  
  90.         return -1;  
  91.     }  
  92.    
  93.     on = 1;  
  94.     /* 设置地址复用许可, 根据具体情况判断是否增加此功能 */  
  95.     if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)  
  96.     {  
  97.         perror("SO_REUSEADDR");  
  98.         return -1;  
  99.     }  
  100.   
  101.     /*加入多播组*/  
  102.     mreq.imr_multiaddr.s_addr = inet_addr(TRAM_STATUS_ADDR);  
  103.     mreq.imr_interface.s_addr = htonl(INADDR_ANY);  
  104.     if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)<br>  
  105.     {  
  106.         perror("setsockopt");  
  107.         return -1;  
  108.     }  
  109.   
  110.     addrlen = sizeof(addr);  
  111.     if ((nbytes = recvfrom(fd, msgbuf, MSGBUFSIZE, 0, (struct sockaddr *)&addr, (socklen_t *)&addrlen)) < 0)  
  112.     {  
  113.         perror("recvfrom");  
  114.         return -1;  
  115.     }  
  116.     printf("recv ok!\n");  
  117.   
  118.     /*退出多播组*/  
  119.     setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));  
  120.     close(fd);  
  121.   
  122.     return 0;  
  123. }  
  124.   
  125.     以上两段程序均截取于已编译可正确执行的源代码,OS:Linux,在两个开发板之间进行组播测试。
posted @ 2017-04-28 11:19  苍月代表我  阅读(5815)  评论(0编辑  收藏  举报