网络编程:用UDP通信实现广播(一对多)的流程
用UDP通信实现广播接收数据:
原理图:
广播流程(bcast.c, bcastrecv .c) 创建UDP套接字 socket(AF_INET, SOCK_DGRAM, 0) 开启广播 int on=1; setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, on, sizeof(on)); 发送数据给广播地址 sendto(sockfd, 发送的数据data, 数据长度size, 0, 广播地址, 地址长度)
函数:
//开启广播 int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); 注意:void *optval和const void *optval的区别 加const是传入参数,没加const不一定是传出参数,传入传出都可以(如果传入的参数要修改,就不能加const) 参数: int sockfd 套接字描述符 int level: 级别socket(SOL_SOCKET), IP,TCP(IPPROTO_IP)定义在socket.h文件中(man 7 socket) int optname 这个参数与level对应,如果level为SOL_SOCKET,本参数 (Ctrl+括号的右边查看宏定义,ctrl+o返回) const void *optval 要设置的值(比如设置广播: 1-开, 0-关闭) socklen_t optlen 值占用空间大小
实现完整代码如下:
#include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <string.h> #include <netinet/in.h> #include <unistd.h> #include <arpa/inet.h> #include <pthread.h> #include <stdbool.h> #include <sys/stat.h> #include <fcntl.h> int main(void) { //1.创建套接字 int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if(sockfd < 0) { perror("socket fail"); return -1; } //开启广播 int on =1; int ret = setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); if(ret < 0) perror("setsockopt error"); //2.发送数据 struct sockaddr_in destAddr; //定一个存储地址,端口号的替代结构体 memset(&destAddr, 0, sizeof(destAddr)); //初始化为0 destAddr.sin_family = AF_INET;//初始化地址族IPV4 destAddr.sin_port = htons(9999); //设置端口号(网络字节序号) destAddr.sin_addr.s_addr = inet_addr("192.168.24.255");//初始化绑定地址, 用INADDR_ANY--表示绑定本机地址 char sendbuffer[]="教师机hello world"; ssize_t size = sendto(sockfd, sendbuffer, sizeof(sendbuffer), 0, (struct sockaddr*)&destAddr, sizeof(destAddr)); if(size <0){ perror("sendto error"); close(sockfd); return -1; } #if 0 //接收反馈数据 char recvbuffer[1024]; size = recvfrom(sockfd, recvbuffer, sizeof(recvbuffer), 0, NULL, NULL); if(size < 0) { perror("recvfrom error"); return -1; } printf("%s ", recvbuffer); #endif close(sockfd); }
接收数据端:
#include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <string.h> #include <netinet/in.h> #include <unistd.h> #include <semaphore.h> #include <stdbool.h> #include <arpa/inet.h> #include <sys/epoll.h> #define MAXSIZE 100 int main(void) { //1.创建套接字 UDP--SOCK_DGRAM int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if(sockfd < 0) { perror("socket fail"); return -1; } //设置地址复用 int on = 1; int ropt = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); //2.绑定 struct sockaddr_in addr; //定一个存储地址,端口号的替代结构体 memset(&addr, 0, sizeof(addr)); //初始化为0 addr.sin_family = AF_INET;//初始化地址族IPV4 addr.sin_port = htons(9999); //设置端口号(网络字节序号) addr.sin_addr.s_addr = INADDR_ANY;//初始化绑定地址, 用INADDR_ANY--表示绑定本机地址 int ret = bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)); if(ret < 0) { perror("bind fail:"); return -1; } //3.接收数据 struct sockaddr_in srcAddr;//保存发送方的地址 socklen_t len = sizeof(srcAddr); char recvbuffer[1024]; ssize_t size = recvfrom(sockfd, recvbuffer, sizeof(recvbuffer), 0, (struct sockaddr*)&srcAddr, &len); if(size < 0) { perror("recvfrom error"); return -1; } printf("%s ", recvbuffer); //关闭套接字 close(sockfd); return 0; }
实现效果:
上一篇:
Java架构师技术进阶路线图
下一篇:
计算机网络——UDP和TCP的对比