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[128] = "I am teacher,this is test packet";
-
- struct sockaddr_in dest_addr;
- dest_addr.sin_family = AF_INET; //协议族,是固定的
- dest_addr.sin_port = htons(atoi(argv[1])); //服务器端口,必须转换为网络字节序
- dest_addr.sin_addr.s_addr = inet_addr(argv[2]); //服务器地址 "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[128] = "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[128];
- // // 获取当前时间
- // time_t current_time = time(NULL);
- // // 转换为本地时间
- // struct tm *tm_now = localtime(¤t_time);
- // // 使用strftime格式化时间
- // char buffer[128];
- // 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[128];
-
- 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[recv_size] = '\0'; // 添加字符串终止符
- // 获取当前时间(实时更新)
- time_t now = time(NULL);
- struct tm *tm_info = localtime(&now);
- char time_buf[128];
- 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;
- }
复制代码 来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |