找回密码
 立即注册
首页 业界区 安全 UDP的广播和组播

UDP的广播和组播

崆蛾寺 2025-6-10 10:50:45
UDP的广播和组播

设计程序,创建UDP套接字,首先检查UDP套接字的广播选项是否启动,如果没有启动,则启动UDP套接字的广播选项。
  1. #include <sys/socket.h>
  2. #include <netinet/in.h>
  3. #include
  4. #include <stdio.h>
  5. #include <errno.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <netinet/ip.h>
  9. #include
  10. #include <sys/socket.h>
  11. #include <netinet/in.h>
  12. #include <netinet/udp.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <sys/types.h>
  16. int main()
  17. {
  18.     //1.创建socket套接字
  19.     int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
  20.         if (udp_socket == -1)
  21.         {
  22.                 fprintf(stderr, "udp socket error,errno:%d,%s\n",errno,strerror(errno));
  23.                 exit(1);
  24.         }
  25.     //2.获取UDP套接字的广播属性
  26.         int flag = -1;
  27.         socklen_t len = 4;
  28.         getsockopt(udp_socket,SOL_SOCKET,SO_BROADCAST,(void *)&flag,&len);
  29.         printf("flag = %d\n",flag); // 0
  30.         //3.设置UDP套接字的广播属性
  31.         int optval = 1;
  32.         setsockopt(udp_socket,SOL_SOCKET,SO_BROADCAST,&optval,sizeof(optval));
  33.         //4.获取UDP套接字的广播属性
  34.         flag = -1;
  35.         getsockopt(udp_socket,SOL_SOCKET,SO_BROADCAST,(void *)&flag,&len);
  36.         printf("flag = %d\n",flag); // 非0
  37.     //5.利用循环每隔5s想广播地址发送数据包
  38.         char buf[128] = "I am teacher,this is test packet";
  39.        
  40.         struct sockaddr_in  dest_addr;
  41.         dest_addr.sin_family                 = AF_INET;                                                 //协议族,是固定的
  42.         dest_addr.sin_port                   = htons(atoi(argv[1]));                        //服务器端口,必须转换为网络字节序
  43.         dest_addr.sin_addr.s_addr   = inet_addr(argv[2]);                        //服务器地址 "192.168.64.xxx"  
  44.         while(1)
  45.         {
  46.                 sendto(udp_socket,buf,strlen(buf),0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
  47.                 sleep(5);
  48.         }
  49.        
  50.         return 0;
  51.    
  52. }
复制代码
小组实现,小组中的每位成员都需要设计程序,要求程序可以加入到一个多播组中并等待服务器发送数据包,并且程序还需要具有发送功能,如果收到数据包则把消息内容输出到终端, 消息内容格式 [消息来源IP  消息时间 ] : 消息内容
  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include
  6. #include <stdio.h>
  7. #include <errno.h>
  8. #include <sys/socket.h>
  9. #include <netinet/in.h>
  10. #include <netinet/ip.h>
  11. #include
  12. #include <sys/socket.h>
  13. #include <netinet/in.h>
  14. #include <netinet/udp.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <sys/types.h>
  18. #include <time.h>
  19. #include <unistd.h>
  20. #include <locale.h>
  21. #define MULADDR "192.168.136.200"
  22. #define PORT 6666
  23. struct sockaddr_in dest_addr;
  24. int udp_socket;
  25. //发送信息
  26. void * send_msg(void *)
  27. {
  28.     char buf[128] = "HELLO WORLD";
  29.     //向多播组发送内容
  30.     while(1)
  31.     {
  32.         sendto(udp_socket, buf, strlen(buf), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
  33.         sleep(5);
  34.     }
  35.     return NULL;
  36. }
  37. //接收信息
  38. // void * recv_msg(void *)
  39. // {
  40. //     struct sockaddr_in source_addr;
  41. //     socklen_t addr_len = sizeof(source_addr);  // 声明变量并初始化
  42. //     char recvbuf[128];
  43. //     // 获取当前时间
  44. //     time_t current_time = time(NULL);
  45. //     // 转换为本地时间
  46. //     struct tm *tm_now = localtime(&current_time);
  47. //     // 使用strftime格式化时间
  48. //     char buffer[128];
  49. //     strftime(buffer, sizeof(buffer), "%Y-%m-%d %H-%M-%S",tm_now);
  50. //     while(1)
  51. //     {
  52. //         //接收收到的信息
  53. //         recvfrom(udp_socket,recvbuf,sizeof(recvbuf),0,(struct sockaddr *)&source_addr, &addr_len);
  54. //         // 打印时间
  55. //         printf("来自:%s,当前时间是:%s,内容:%s\n", inet_ntoa(source_addr.sin_addr),buffer,recvbuf);
  56. //         bzero(recvbuf,sizeof(recvbuf));
  57. //     }
  58. // }
  59. // 接收信息
  60. void *recv_msg(void *) {
  61.     struct sockaddr_in source_addr;
  62.     socklen_t addr_len = sizeof(source_addr);  // 定义地址长度变量
  63.     char recvbuf[128];
  64.    
  65.     while (1) {
  66.         // 重置地址长度,防止被前次调用修改
  67.         addr_len = sizeof(source_addr);
  68.         
  69.         // 接收数据
  70.         ssize_t recv_size = recvfrom(
  71.             udp_socket,
  72.             recvbuf,
  73.             sizeof(recvbuf) - 1,  // 预留一个字节给字符串终止符
  74.             0,
  75.             (struct sockaddr *)&source_addr,
  76.             &addr_len  // 正确传递地址长度变量的指针
  77.         );
  78.         // 处理接收结果
  79.         if (recv_size > 0) {
  80.             recvbuf[recv_size] = '\0';  // 添加字符串终止符
  81.             // 获取当前时间(实时更新)
  82.             time_t now = time(NULL);
  83.             struct tm *tm_info = localtime(&now);
  84.             char time_buf[128];
  85.             strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", tm_info);
  86.             printf("来自:%s,时间:%s,内容:%s\n",
  87.                   inet_ntoa(source_addr.sin_addr), time_buf, recvbuf);
  88.         } else if (recv_size == -1) {
  89.             perror("recvfrom 错误");
  90.             break;
  91.         }
  92.     }
  93.     return NULL;
  94. }
  95. int main()
  96. {
  97.     //1.创建socket套接字
  98.     udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
  99.         if (udp_socket == -1)
  100.         {
  101.                 fprintf(stderr, "udp socket error,errno:%d,%s\n",errno,strerror(errno));
  102.                 exit(1);
  103.         }
  104.     //2.设置UDP套接字的组播属性,并加入组播组
  105.     // struct ip_mreqn {
  106.     //     struct in_addr imr_multiaddr; /* IP multicast group
  107.     //                                      address */
  108.     //     struct in_addr imr_address;   /* IP address of local
  109.     //                                      interface */
  110.     //     int            imr_ifindex;   /* interface index */
  111.     // };
  112.     struct ip_mreq mreq;
  113.     mreq.imr_multiaddr.s_addr=inet_addr(MULADDR);
  114.     mreq.imr_interface.s_addr=htonl(INADDR_ANY);
  115.         setsockopt(udp_socket,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));
  116.     //3.创建的的套接字和本地端口和ip绑定
  117.     struct sockaddr_in host_addr;
  118.     host_addr.sin_family=AF_INET;
  119.     host_addr.sin_port=htons(PORT);
  120.     host_addr.sin_addr.s_addr=htonl(INADDR_ANY);
  121.     bind(udp_socket,(struct sockaddr *)&host_addr,sizeof(host_addr));
  122.     // 4.向目标主机发送消息,需要设置目标端口和目标地址
  123.         memset(&dest_addr, 0, sizeof(dest_addr));
  124.     dest_addr.sin_family = AF_INET;
  125.     dest_addr.sin_port = htons(PORT);
  126.     dest_addr.sin_addr.s_addr = inet_addr(MULADDR);
  127.     pthread_t recv_thread,send_thread;
  128.     pthread_create(&recv_thread,NULL,recv_msg,NULL);
  129.     pthread_create(&send_thread,NULL,send_msg,NULL);
  130.     pthread_join(recv_thread,NULL);
  131.     pthread_join(send_thread,NULL);
  132.     close(udp_socket);
  133.     return 0;
  134. }
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册