UDP 广播
来源:互联网 发布:台湾进出口数据 编辑:程序博客网 时间:2024/04/28 18:57
linux 广播
广播是一台主机向局域网内的所有主机发送数据。这时,同一网段的所有主机都能接收到数据。发送广播包的步骤大致如下:
(1)确定一个发送广播的接口,如eth0
(2)确定广播的地址,通过ioctl函数,请求码设置为SIOCGIFBRDADDR得到广播的地址
(3)使用这个广播地址进行广播
在局域网内,广播通常用来探测服务器。
广播发送端:
1 主机: 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 #include<unistd.h> 6 #include<string.h> 7 #include<sys/socket.h> 8 #include<arpa/inet.h> 9 #include<netinet/in.h> 10 #include<sys/types.h> 11 #include<netdb.h> 12 #include <sys/ioctl.h> 13 #include <net/if.h> 14 /** 15 客户端实现广播 16 17 18 **/ 19 #define IP_FOUND "IP_FOUND" 20 #define IP_FOUND_ACK "IP_FOUND_ACK" 21 #define IFNAME "eth0" 22 #define MCAST_PORT 9999 23 int main(int argc,char*argv[]){ 24 int ret=-1; 25 26 27 struct sockaddr_in from_addr;//服务端地址 28 int from_len=sizeof(from_addr); 29 int count=-1; 30 fd_set readfd;//读文件描述符集合 31 char buffer[1024]; 32 struct timeval timeout; 33 timeout.tv_sec=2;//超时时间为2秒 34 timeout.tv_usec=0; 35 36 int sock=-1; 37 sock=socket(AF_INET,SOCK_DGRAM,0);//建立数据报套接字 38 if(sock<0){ 39 printf("HandleIPFound:sock init error\n"); 40 return; 41 } 42 43 44 //将使用的网络接口名字复制到ifr.ifr_name中,由于不同的网卡接口的广播地址是不一样的,因此指定网卡接口 45 46 struct ifreq ifr; 47 strncpy(ifr.ifr_name,IFNAME,strlen(IFNAME)); 48 //发送命令,获得网络接口的广播地址 49 if(ioctl(sock,SIOCGIFBRDADDR,&ifr)==-1){ 50 perror("ioctl error"); 51 return; 52 } 53 54 //将获得的广播地址复制到broadcast_addr 55 int so_broadcast=1; 56 struct sockaddr_in broadcast_addr;//广播地址 57 memcpy(&broadcast_addr,&ifr.ifr_broadaddr,sizeof(struct sockaddr_in)); 58 59 60 //设置广播端口号 61 printf("broadcast IP is:%s\n",inet_ntoa(broadcast_addr.sin_addr)); 62 broadcast_addr.sin_family=AF_INET; 63 broadcast_addr.sin_port=htons(MCAST_PORT); 64 //默认的套接字描述符sock是不支持广播,必须设置套接字描述符以支持广播 65 ret=setsockopt(sock,SOL_SOCKET,SO_BROADCAST,&so_broadcast,sizeof(so_broadcast)); 66 67 68 69 //发送多次广播,看网络上是否有服务器存在 70 int times=10; 71 int i=0; 72 for(i=0;i<times;i++){//一共发送10次广播,每次等待2秒是否有回应 73 //广播发送服务器地址请求 74 timeout.tv_sec=2;//超时时间为2秒 75 timeout.tv_usec=0; 76 ret=sendto(sock,IP_FOUND,strlen(IP_FOUND),0,(struct sockaddr*)&broadcast_addr,sizeof(broadcast_addr)); 77 if(ret==-1){ 78 continue; 79 } 80 81 //文件描述符清0 82 FD_ZERO(&readfd); 83 //将套接字文件描述符加入到文件描述符集合中 84 FD_SET(sock,&readfd); 85 //select侦听是否有数据到来 86 ret=select(sock+1,&readfd,NULL,NULL,&timeout); 87 switch(ret){ 88 case -1: 89 break; 90 case 0: 91 printf("timeout\n"); 92 break; 93 default: 94 //接收到数据 95 if(FD_ISSET(sock,&readfd)){ 96 count=recvfrom(sock,buffer,1024,0,(struct sockaddr*)&from_addr,&from_len);//from_addr为服务器端地址 97 printf("recvmsg is %s\n",buffer); 98 if(strstr(buffer,IP_FOUND_ACK)){ 99 printf("found server IP is:%s\n",inet_ntoa(from_addr.sin_addr));100 //服务器端的发送端口号101 printf("Server Port:%d\n",htons(from_addr.sin_port));102 }103 return;104 105 }106 break;107 108 }109 }110 return;111 }
广播接收端:
1 #include <stdio.h> 2 #include <string.h> 3 #include <sys/types.h> 4 #include <sys/socket.h> 5 #include <fcntl.h> 6 #include <linux/in.h> 7 #include <stdlib.h> 8 /** 9 广播接收端代码10 **/11 #define IP_FOUND "IP_FOUND"12 #define IP_FOUND_ACK "IP_FOUND_ACK"13 #define PORT 999914 int main(int argc,char*argv[]){15 int ret=-1;16 int sock;17 struct sockaddr_in server_addr;//服务器端地址18 struct sockaddr_in from_addr;//客户端地址19 int from_len=sizeof(struct sockaddr_in);20 int count=-1;21 fd_set readfd;//读文件描述符集合22 char buffer[1024];23 struct timeval timeout;24 timeout.tv_sec=2;25 timeout.tv_usec=0;26 sock=socket(AF_INET,SOCK_DGRAM,0);//建立数据报套接字27 if(sock<0){28 perror("sock error");29 return;30 }31 32 memset((void*)&server_addr,0,sizeof(struct sockaddr_in));33 server_addr.sin_family=AF_INET;34 server_addr.sin_addr.s_addr=htons(INADDR_ANY);35 server_addr.sin_port=htons(PORT);36 //将地址结构绑定到套接字上./37 ret=bind(sock,(struct sockaddr*)&server_addr,sizeof(server_addr));38 if(ret<0){39 perror("bind error");40 return;41 }42 43 while(1){44 timeout.tv_sec=2;45 timeout.tv_usec=0;46 //文件描述符集合清047 FD_ZERO(&readfd);48 //将套接字描述符加入到文件描述符集合49 FD_SET(sock,&readfd);50 //select侦听是否有数据到来51 ret=select(sock+1,&readfd,NULL,NULL,&timeout);//侦听是否可读52 printf("ret=%d\n",ret);53 switch(ret){54 case -1://发生错误55 break;56 case 0://超时57 printf("timeout\n");58 break;59 default:60 if(FD_ISSET(sock,&readfd)){61 count=recvfrom(sock,buffer,1024,0,(struct sockaddr*)&from_addr,&from_len);//接收客户端发送的数据62 //from_addr保存客户端的地址结构63 if(strstr(buffer,IP_FOUND)){64 //响应客户端请求65 //打印客户端的IP地址66 printf("Client IP is%s\n",inet_ntoa(from_addr.sin_addr));67 //打印客户端的端口号68 printf("Client Send Port:%d\n",ntohs(from_addr.sin_port));69 memcpy(buffer,IP_FOUND_ACK,strlen(IP_FOUND_ACK)+1);70 count=sendto(sock,buffer,strlen(buffer),0,(struct sockaddr*)&from_addr,from_len);//将数据发送给客户端71 }72 return;73 }74 break;75 }76 }77 return;78 }
0 0
- UDP广播
- UDP广播
- udp广播
- UDP广播
- UDP广播
- UDP广播
- UDP 广播
- UDP广播
- UDP广播
- UDP广播
- udp广播
- udp广播
- UDP广播
- UDP广播
- UDP广播
- udp广播
- udp广播与直接广播
- UDP广播,UDP多播
- ScrollView 嵌套listView,各自有各自的滑动
- Android解析Intent Filter详细过程
- 用过的一些Android设备调试特性注意点(挖坑帖)
- 一. Mybatis入门
- ubuntu源详解
- UDP 广播
- 作为一个屌丝程序员不得不收藏的工具类 一 IP获取工具类
- Android----uses-sdk
- singleTop和singleTask有什么区别?( Activity 四种加载模式详解)
- Jersey 中抛出 should not consume any form parameter. exception
- 关于tableView的separatoreLine隐藏
- 牛叔的lua研究报告——dofile和require
- Gridview很漂亮的样式
- 在SQL数据库中设定uniqueidentifier类型的值为Guid.Empty的做法