崆蛾寺 发表于 2025-6-10 10:50:45

UDP的广播和组播

UDP的广播和组播

设计程序,创建UDP套接字,首先检查UDP套接字的广播选项是否启动,如果没有启动,则启动UDP套接字的广播选项。
#include <sys/socket.h>
#include <netinet/in.h>
#include
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

int main()
{
    //1.创建socket套接字
    int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
        if (udp_socket == -1)
        {
                fprintf(stderr, "udp socket error,errno:%d,%s\n",errno,strerror(errno));
                exit(1);
        }

    //2.获取UDP套接字的广播属性
        int flag = -1;
        socklen_t len = 4;
        getsockopt(udp_socket,SOL_SOCKET,SO_BROADCAST,(void *)&flag,&len);

        printf("flag = %d\n",flag); // 0

        //3.设置UDP套接字的广播属性
        int optval = 1;
        setsockopt(udp_socket,SOL_SOCKET,SO_BROADCAST,&optval,sizeof(optval));

        //4.获取UDP套接字的广播属性
        flag = -1;
        getsockopt(udp_socket,SOL_SOCKET,SO_BROADCAST,(void *)&flag,&len);
        printf("flag = %d\n",flag); // 非0

    //5.利用循环每隔5s想广播地址发送数据包
        char buf = "I am teacher,this is test packet";
       
        struct sockaddr_indest_addr;
        dest_addr.sin_family                 = AF_INET;                                                 //协议族,是固定的
        dest_addr.sin_port                   = htons(atoi(argv));                        //服务器端口,必须转换为网络字节序
        dest_addr.sin_addr.s_addr   = inet_addr(argv);                        //服务器地址 "192.168.64.xxx"

        while(1)
        {
                sendto(udp_socket,buf,strlen(buf),0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
                sleep(5);
        }
       

        return 0;
   
}小组实现,小组中的每位成员都需要设计程序,要求程序可以加入到一个多播组中并等待服务器发送数据包,并且程序还需要具有发送功能,如果收到数据包则把消息内容输出到终端, 消息内容格式 [消息来源IP消息时间 ] : 消息内容
#include <stdio.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <locale.h>

#define MULADDR "192.168.136.200"
#define PORT 6666
struct sockaddr_in dest_addr;
int udp_socket;

//发送信息
void * send_msg(void *)
{
    char buf = "HELLO WORLD";
    //向多播组发送内容
    while(1)
    {
      sendto(udp_socket, buf, strlen(buf), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
      sleep(5);
    }
    return NULL;
}

//接收信息
// void * recv_msg(void *)
// {
//   struct sockaddr_in source_addr;
//   socklen_t addr_len = sizeof(source_addr);// 声明变量并初始化
//   char recvbuf;
//   // 获取当前时间
//   time_t current_time = time(NULL);
//   // 转换为本地时间
//   struct tm *tm_now = localtime(&current_time);
//   // 使用strftime格式化时间
//   char buffer;
//   strftime(buffer, sizeof(buffer), "%Y-%m-%d %H-%M-%S",tm_now);
//   while(1)
//   {
//         //接收收到的信息
//         recvfrom(udp_socket,recvbuf,sizeof(recvbuf),0,(struct sockaddr *)&source_addr, &addr_len);
//         // 打印时间
//         printf("来自:%s,当前时间是:%s,内容:%s\n", inet_ntoa(source_addr.sin_addr),buffer,recvbuf);
//         bzero(recvbuf,sizeof(recvbuf));
//   }
// }
// 接收信息
void *recv_msg(void *) {
    struct sockaddr_in source_addr;
    socklen_t addr_len = sizeof(source_addr);// 定义地址长度变量
    char recvbuf;
   
    while (1) {
      // 重置地址长度,防止被前次调用修改
      addr_len = sizeof(source_addr);
      
      // 接收数据
      ssize_t recv_size = recvfrom(
            udp_socket,
            recvbuf,
            sizeof(recvbuf) - 1,// 预留一个字节给字符串终止符
            0,
            (struct sockaddr *)&source_addr,
            &addr_len// 正确传递地址长度变量的指针
      );

      // 处理接收结果
      if (recv_size > 0) {
            recvbuf = '\0';// 添加字符串终止符
            // 获取当前时间(实时更新)
            time_t now = time(NULL);
            struct tm *tm_info = localtime(&now);
            char time_buf;
            strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", tm_info);
            printf("来自:%s,时间:%s,内容:%s\n",
                  inet_ntoa(source_addr.sin_addr), time_buf, recvbuf);
      } else if (recv_size == -1) {
            perror("recvfrom 错误");
            break;
      }
    }
    return NULL;
}

int main()
{
    //1.创建socket套接字
    udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
        if (udp_socket == -1)
        {
                fprintf(stderr, "udp socket error,errno:%d,%s\n",errno,strerror(errno));
                exit(1);
        }

    //2.设置UDP套接字的组播属性,并加入组播组
    // struct ip_mreqn {
    //   struct in_addr imr_multiaddr; /* IP multicast group
    //                                    address */
    //   struct in_addr imr_address;   /* IP address of local
    //                                    interface */
    //   int            imr_ifindex;   /* interface index */
    // };
    struct ip_mreq mreq;
    mreq.imr_multiaddr.s_addr=inet_addr(MULADDR);
    mreq.imr_interface.s_addr=htonl(INADDR_ANY);
        setsockopt(udp_socket,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));


    //3.创建的的套接字和本地端口和ip绑定
    struct sockaddr_in host_addr;
    host_addr.sin_family=AF_INET;
    host_addr.sin_port=htons(PORT);
    host_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    bind(udp_socket,(struct sockaddr *)&host_addr,sizeof(host_addr));

    // 4.向目标主机发送消息,需要设置目标端口和目标地址

        memset(&dest_addr, 0, sizeof(dest_addr));
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(PORT);
    dest_addr.sin_addr.s_addr = inet_addr(MULADDR);

    pthread_t recv_thread,send_thread;
    pthread_create(&recv_thread,NULL,recv_msg,NULL);
    pthread_create(&send_thread,NULL,send_msg,NULL);

    pthread_join(recv_thread,NULL);
    pthread_join(send_thread,NULL);

    close(udp_socket);
    return 0;
}
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: UDP的广播和组播