socket的局域网广播

来源:互联网 发布:ysl 口红 知乎 编辑:程序博客网 时间:2024/05/19 14:16

广播

1. TCP/IP协议栈中, 传输层只有UDP可以广播.

2. 只能对同一子网内部广播, 广播数据包不经过路由器.

3. UDP的广播地址为255.255.255.255

4. 在winsock实现中, 有一个选项对应是否允许广播.linux下必须调用setsockopt打开该选项.

5. 打开后, 用sendto向255.255.255.255发送的数据包全部广播.

很多局域网都定义了一个特殊的保留地址, 称为广播地址. 当信息头中目的地址域的内容为广播地址时, 该帧被局域网上所有计算机接收. 

这个过程称为广播.合法的广播地址就是主机的网络地址加上最大的主机号。网络地址通过机器的ip地址与子网掩码按位与得出,我们

以ip地址为10.78.202.175 ,子网掩码为255.0.0.0。


好了,说白了向局域网发送广播,就是向ip地址为255.255.255.255的指定端口发送数据。当然,由于此ip的用户根本就不存在,那么,

你就只能选择使用UDP的方式发送数据。

同时,当你将一组数据发送到路由,它发现用户的ip是255.255.255.255。那么这时,它会立刻明白,好哇,原来你是想将数据发往整个

网路(这里包括外网和内网),它当然不会允许你这么干,但是又不能不发,于是他就将数据发往内网的每个用户。

发送者:

1.首先创建socket

[cpp] view plain copy
  1. cfd = socket(AF_INET,SOCK_DGRAM,0)  
2.UDP默认不支持广播,你需要打开

[cpp] view plain copy
  1. int n = 1;  //  0表示关闭属性,非0表示打开属性  
  2. setsockopt(cfd,SOL_SOCKET,SO_BROADCAST,&n,sizeof(n));  
3.设置你要讲数据发给谁

[cpp] view plain copy
  1. struct sockaddr_in si;  
  2. si.sin_family = AF_INET;  
  3. si.sin_port = htons(8000);  
  4. si.sin_addr.s_addr = inet_addr("255.255.255.255");  
4.废话少说,发送数据吧

[cpp] view plain copy
  1. sendto(cfd,buffer,buffer_size,0,(struct sockaddr *)&si,sizeof(si));  
5.养成好习惯,最后被忘了关闭socket
[cpp] view plain copy
  1. close(cfd);  

接受者:

1.打开socket

[cpp] view plain copy
  1. int cfd = socket(AF_INET, SOCK_DGRAM, 0);  

2.将你的socket与指定的端口绑定,用于接受数据,你懂得

[cpp] view plain copy
  1. struct sockaddr_in  si;  
  2. si.sin_family = AF_INET;  
  3. si.sin_port = htons(8000);//这里的端口要与上面的端口保持一致,亲,你注意到了没?  
  4. si.sin_addr.s_addr = INADDR_ANY;   
  5. int ret = bind(cfd, (struct sockaddr *)&si, sizeof(si));  

3.好了,可以开始接受数据了
[cpp] view plain copy
  1. recv(cfd,buf,22,0);  
4.还是那句话,用完记得还哭
[cpp] view plain copy
  1. close(cfd);  


源代码:

发送者:

[cpp] view plain copy
  1. #include <stdio.h>  
  2. #include <sys/types.h>  
  3. #include <sys/socket.h>  
  4. #include <string.h>  
  5. #include <netinet/in.h>  
  6.   
  7. int main()  
  8. {  
  9.     int cfd = socket(AF_INET,SOCK_DGRAM,0);  
  10.   
  11.     int n = 1;  //  0表示关闭属性,非0表示打开属性  
  12.     setsockopt(cfd, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n));//广播设置  
  13.   
  14.     struct sockaddr_in si;  
  15.     si.sin_family = AF_INET;  
  16.     si.sin_port = htons(8000);  
  17.     si.sin_addr.s_addr = inet_addr("255.255.255.255");  //这是对局域网全网段  
  18.   
  19.     char buf[22];  
  20.     while(1)  
  21.     {     
  22.         bzero(buf,22);  
  23.         printf("Input:");  
  24.         scanf("%s",buf);  
  25.         sendto(cfd,buf,22,0,(struct sockaddr *)&si,sizeof(si));  
  26.     }  
  27.   
  28.     close(cfd);  
  29.     return 0;  
  30. }  

接受者:

[cpp] view plain copy
  1. #include <stdio.h>  
  2. #include <sys/types.h>          /* See NOTES */  
  3. #include <sys/socket.h>  
  4. #include <string.h>  
  5. #include <netinet/in.h>  
  6.   
  7. int main()  
  8. {  
  9.     int cfd = socket(AF_INET, SOCK_DGRAM, 0);  
  10.     if(cfd < 0)  
  11.     {  
  12.         perror("socket");  
  13.         return 0;  
  14.     }  
  15.   
  16.     struct sockaddr_in  si;  
  17.     int addrlen = sizeof(si);  
  18.     bzero(&si,addrlen);  
  19.     si.sin_family = AF_INET;  
  20.     si.sin_port = htons(8000);  
  21.     si.sin_addr.s_addr = INADDR_ANY;    
  22.       
  23.     //绑定  
  24.     int ret = bind(cfd, (struct sockaddr *)&si, sizeof(si));  
  25.     if(ret == -1)  
  26.     {  
  27.         perror("bind");  
  28.         return 0;  
  29.     }   
  30.   
  31.     char buf[22];  
  32.     struct sockaddr_in si_recv;  
  33.     addrlen = sizeof(si_recv);  
  34.     bzero(&si_recv,addrlen);  
  35.     si_recv.sin_family = AF_INET;  
  36.     si_recv.sin_port = htons(8000);  
  37.     si_recv.sin_addr.s_addr = INADDR_ANY;    
  38.     while(1)  
  39.     {  
  40.         bzero(buf,22);  
  41.         recvfrom(cfd, buf, 21, 0, (struct sockaddr*)&si_recv, &addrlen);  
  42.         printf("[%s(%d)]:%s\n",(char *)inet_ntoa(si_recv.sin_addr),si_recv.sin_port,buf);  
  43.     }  
  44.   
  45.     close(cfd);  
  46.     return 0;  
  47. }