Linux 网络通信之广播

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 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <sys/types.h>
 5 #include <sys/socket.h>
 6 #include <arpa/inet.h>
 7 #include <netinet/in.h>
 8 #include <string.h>
 9 
10 #define  err_log(log) do{perror(log); exit(1);}while(0)
11 
12 #define  N 128
13 
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 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <sys/types.h>
 5 #include <sys/socket.h>
 6 #include <arpa/inet.h>
 7 #include <netinet/in.h>
 8 #include <string.h>
 9 
10 #define  err_log(log) do{perror(log); exit(1);}while(0)
11 #define  N  128
12 
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
", buf, inet_ntoa(srcaddr.sin_addr), ntohs(srcaddr.sin_port));
43     }
44 
45     return 0;
46 }
原文地址:https://www.cnblogs.com/yangziwen0709/p/5025902.html