Linux网络编程之广播
来源:互联网 发布:淘宝店铺图标设计 编辑:程序博客网 时间:2024/05/02 02:56
1.概念前面介绍的TCP,UDP都是单播方式,即一对一.而广播是一台主机向局域网内的所有主机发送数据。这时,同一网段的所有主机都能接收到数据。发送广播包的步骤大致如下:(1)确定一个发送广播的接口,如eth0(2)确定广播的地址,通过ioctl函数,请求码设置为SIOCGIFBRDADDR得到广播的地址(3)使用这个广播地址进行广播由于TCP协议是端到端的协议,在通信之前,必须建立连接,三次握手之后才能发送数据。而广播是一对多的通信,所以TCP不支持广播。在局域网内,广播通常用来探测服务器。2. 探测服务器实例这个例子通过在局域网内发送广播包,收到广播包的服务器,应答主机。这样,就能够探测到局域网内的服务器。主机: /**客户端实现广播**/ #define IP_FOUND "IP_FOUND" #define IP_FOUND_ACK "IP_FOUND_ACK" #define IFNAME "eth0" #define MCAST_PORT 9999 int main(int argc,char*argv[]){ int ret=-1; int sock=-1; int so_broadcast=1; struct ifreq ifr; struct sockaddr_in broadcast_addr;//广播地址struct sockaddr_in from_addr;//服务端地址int from_len=sizeof(from_addr); int count=-1; fd_set readfd;//读文件描述符集合char buffer[1024]; struct timeval timeout; timeout.tv_sec=2;//超时时间为2秒timeout.tv_usec=0; sock=socket(AF_INET,SOCK_DGRAM,0);//建立数据报套接字if(sock<0){ printf("HandleIPFound:sock init error\n"); return; } //将使用的网络接口名字复制到ifr.ifr_name中,由于不同的网卡接口的广播地址是不一样的,因此指定网卡接口strncpy(ifr.ifr_name,IFNAME,strlen(IFNAME)); //发送命令,获得网络接口的广播地址if(ioctl(sock,SIOCGIFBRDADDR,&ifr)==-1){ perror("ioctl error"); return; } //将获得的广播地址复制到broadcast_addr memcpy(&broadcast_addr,&ifr.ifr_broadaddr,sizeof(struct sockaddr_in)); //设置广播端口号printf("broadcast IP is:%s\n",inet_ntoa(broadcast_addr.sin_addr)); broadcast_addr.sin_family=AF_INET; broadcast_addr.sin_port=htons(MCAST_PORT); //默认的套接字描述符sock是不支持广播,必须设置套接字描述符以支持广播ret=setsockopt(sock,SOL_SOCKET,SO_BROADCAST,&so_broadcast,sizeof(so_broadcast)); //发送多次广播,看网络上是否有服务器存在int times=10; int i=0; for(i=0;i //广播发送服务器地址请求 timeout.tv_sec=2;//超时时间为2秒 timeout.tv_usec=0; ret=sendto(sock,IP_FOUND,strlen(IP_FOUND),0,(struct sockaddr*)&broadcast_addr,sizeof(broadcast_addr)); if(ret==-1){ continue; } //文件描述符清0 FD_ZERO(&readfd); //将套接字文件描述符加入到文件描述符集合中FD_SET(sock,&readfd); //select侦听是否有数据到来ret=select(sock+1,&readfd,NULL,NULL,&timeout); switch(ret){ case -1: break; case 0: printf("timeout\n"); break; default: //接收到数据 if(FD_ISSET(sock,&readfd)){ count=recvfrom(sock,buffer,1024,0,(struct sockaddr*)&from_addr,&from_len);//from_addr为服务器端地址 printf("recvmsg is %s\n",buffer); if(strstr(buffer,IP_FOUND_ACK)){ printf("found server IP is:%s\n",inet_ntoa(from_addr.sin_addr)); //服务器端的发送端口号 printf("Server Port:%d\n",htons(from_addr.sin_port)); } return; } break; } } return; }服务器: /**广播服务器端代码**/ #define IP_FOUND "IP_FOUND" #define IP_FOUND_ACK "IP_FOUND_ACK" #define PORT 9999 int main(int argc,char*argv[]){ int ret=-1; int sock; struct sockaddr_in server_addr;//服务器端地址 struct sockaddr_in from_addr;//客户端地址 int from_len=sizeof(struct sockaddr_in); int count=-1; fd_set readfd;//读文件描述符集合 char buffer[1024]; struct timeval timeout; timeout.tv_sec=2; timeout.tv_usec=0; sock=socket(AF_INET,SOCK_DGRAM,0);//建立数据报套接字 if(sock<0){ perror("sock error"); return; } memset((void*)&server_addr,0,sizeof(struct sockaddr_in)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=htons(INADDR_ANY); server_addr.sin_port=htons(PORT); //将地址结构绑定到套接字上./ret=bind(sock,(struct sockaddr*)&server_addr,sizeof(server_addr)); if(ret<0){ perror("bind error"); return; } while(1){ timeout.tv_sec=2; timeout.tv_usec=0; //文件描述符集合清0 FD_ZERO(&readfd); //将套接字描述符加入到文件描述符集合FD_SET(sock,&readfd); //select侦听是否有数据到来ret=select(sock+1,&readfd,NULL,NULL,&timeout);//侦听是否可读printf("ret=%d\n",ret); switch(ret){ case -1://发生错误break; case 0://超时printf("timeout\n"); break; default: if(FD_ISSET(sock,&readfd)){ count=recvfrom(sock,buffer,1024,0,(struct sockaddr*)&from_addr,&from_len);//接收客户端发送的数据 //from_addr保存客户端的地址结构 if(strstr(buffer,IP_FOUND)){ //响应客户端请求 //打印客户端的IP地址 printf("Client IP is%s\n",inet_ntoa(from_addr.sin_addr)); //打印客户端的端口号 printf("Client Send Port:%d\n",ntohs(from_addr.sin_port)); memcpy(buffer,IP_FOUND_ACK,strlen(IP_FOUND_ACK)+1); count=sendto(sock,buffer,strlen(buffer),0,(struct sockaddr*)&from_addr,from_len);//将数据发送给客户端 } return; } break; } } return; }说明: 由于默认的套接字是不支持广播的,所以必须设置套接字选项(setsockopt)来支持广播。接口的广播地址通过ioctl函数得到。广播是基于UDP协议的。MAC地址是FF:FF:FF:FF:FF:FF.
0 0
- Linux网络编程之广播
- Linux网络编程之广播
- Linux网络编程之广播
- Linux网络编程之广播
- Linux网络编程之广播
- Linux网络编程之广播
- linux网络编程之广播编程
- Linux网络编程 之 UDP 广播
- Linux网络编程 之 UDP 广播 .
- Linux网络编程 之 UDP 广播 .
- 【Linux网络编程】广播
- linux网络编程:广播编程
- Linux网络编程[网络中的广播]
- linux 网络编程(广播的编程)
- Linux网络编程——广播
- Linux网络编程——广播
- 【Linux网络编程】广播地址介绍
- Linux网络编程——广播
- Java - Jar的解压和打包
- python openstack API 系列(Nova)
- MYSQL服务器my.cnf配置文档中文详解
- 【LeetCode006算法/编程练习C++】ZigZag Conversion //折形string重新排序
- iOS中几种数据持久化方案
- Linux网络编程之广播
- 设计模式——解释器模式
- 基于注解的Spring AOP的配置和使用
- BFS(广搜) 翻币问题
- Matlab与线性代数--矩阵的奇异值和奇异值分解
- Tiling ,Tri Tiling(递推)
- angularjs中回车键触发某一事件
- Linux 进程间通信 基础
- 动态添加Fragment