IP地址用来标识网络中的一台主机。IPV4协议用一个32位的无符号数表示网络地址,包括网络号和主机号。子网掩码表示IP地址中网络号占几个字节。
每个网段都有对应的广播地址。以C类网段192.168.1.x为例,其中最小的地址192.168.1.0代表该网段;而最大的地址192.168.1.255则是该网段中的广播地址。当我们想这个地址发送数据包时,该网段的所有主机都会接收并处理。
广播包的发送和接收通过UDP套接字实现
广播包发送流程如下:
(1)创建UDP套接字;socket(AF_INET, SOCK_DGRAM, 0)
(2)填充广播信息结构体;struct sockaddr_in
(3)设置套接字选项允许发送广播包;setsockopt(, ,SO_BROADCAST, ,)
(4)发送数据包;sendto( )
send.c
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 10 #define err_log(log) do{perror(log); exit(1);}while(0)11 12 #define N 12813 14 int main(int argc, const char *argv[])15 {16 17 int sockfd;18 struct sockaddr_in broadcastaddr;19 char buf[N] = { 0};20 21 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)22 {23 err_log("fail to socket");24 }25 26 broadcastaddr.sin_family = AF_INET;27 broadcastaddr.sin_addr.s_addr = inet_addr("192.168.1.255");28 broadcastaddr.sin_port = htons(10000);29 30 int optval = 1;31 32 if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(int)) < 0)33 {34 err_log("fail to setsockopt");35 }36 37 while(1)38 {39 printf("Input > ");40 fgets(buf, N, stdin);41 if(sendto(sockfd,buf, N, 0, (struct sockaddr *)&broadcastaddr, sizeof(broadcastaddr)) < 0)42 {43 err_log("fail to sendto");44 }45 46 }47 48 return 0;49 }
广播包接收流程如下:
(1)创建UDP套接字;socket(AF_INET, SOCK_DGRAM, 0)
(2)填充广播信息结构体;struct sockaddr_in
(3)绑定地址和端口;bind( )
(4)接收数据包;recvfrom( )
recv.c
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 10 #define err_log(log) do{perror(log); exit(1);}while(0)11 #define N 12812 13 int main(int argc, const char *argv[])14 {15 16 int sockfd;17 char buf[N];18 struct sockaddr_in broadcastaddr, srcaddr;19 20 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)21 {22 err_log("fail to socket");23 }24 25 broadcastaddr.sin_family = AF_INET;26 broadcastaddr.sin_addr.s_addr = inet_addr("192.168.1.255");27 broadcastaddr.sin_port = htons(10000);28 29 if(bind(sockfd, (struct sockaddr*)&broadcastaddr, sizeof(broadcastaddr)) < 0)30 {31 err_log("fail to bind");32 }33 34 socklen_t addrlen = sizeof(struct sockaddr);35 36 while(1)37 {38 if(recvfrom(sockfd,buf, N, 0, (struct sockaddr *)&srcaddr, &addrlen) < 0)39 {40 err_log("fail to sendto");41 }42 printf("buf:%s ---> %s %d\n", buf, inet_ntoa(srcaddr.sin_addr), ntohs(srcaddr.sin_port));43 }44 45 return 0;46 }