嵌入式 Linux下进行广播包交互示例
2014-04-29 13:54
429 查看
服务器端也就是接受广播包:
客户端发送广播查找服务器:
注意:
1、程序是死循环完成接收或者发送广播包
2、程序没有内存泄漏问题
3、程序没有接收乱码的问题服务器端运行效果:
=====================================Send Broadcast========================================
recvmsg is IP_FOUND_ACK ,The length of recvmsg is 12
found server IP is:10.10.2.59
Server Port:9999
=====================================Send Broadcast========================================
recvmsg is IP_FOUND_ACK ,The length of recvmsg is 12
found server IP is:10.10.2.59
Server Port:9999
客户端运行效果:
=============================Recv Broadcast===================================
ret=1
Client IP is 10.10.2.59
Client Send Port:33784
=============================Recv Broadcast===================================
ret=1
Client IP is 10.10.2.155
Client Send Port:38542
#include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <fcntl.h> #include <linux/in.h> #include <stdlib.h> /** 广播接收端代码 **/ #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){ printf("=============================Recv Broadcast===================================\n"); 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",(char *)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);//将数据发送给客户端 } } break; } } return; }
客户端发送广播查找服务器:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/types.h> #include <netdb.h> #include <sys/ioctl.h> #include <net/if.h> /** 客户端实现广播 **/ #define IP_FOUND "IP_FOUND" #define IP_FOUND_ACK "IP_FOUND_ACK" #define IFNAME "eth0" #define MCAST_PORT 9999 #define MAX_BROADCAST_NUM 16 int main(int argc,char*argv[]){ int ret=-1; 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; int sock=-1; sock=socket(AF_INET,SOCK_DGRAM,0);//建立数据报套接字 if(sock<0){ printf("HandleIPFound:sock init error\n"); return; } //将使用的网络接口名字复制到ifr.ifr_name中,由于不同的网卡接口的广播地址是不一样的,因此指定网卡接口 struct ifreq ifr; bzero(&ifr, sizeof(ifr)); //strcpy(ifr.ifr_name, "eth0"); strncpy(ifr.ifr_name,IFNAME,strlen(IFNAME)); //发送命令,获得网络接口的广播地址 if(ioctl(sock,SIOCGIFBRDADDR,&ifr)==-1){ perror("ioctl error"); return; } //将获得的广播地址复制到broadcast_addr int so_broadcast=1; struct sockaddr_in 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)); while(1) { sleep(1); printf("=====================================Send Broadcast========================================\n"); //发送多次广播,看网络上是否有服务器存在 int times = 1; int i=0; for(i=0;i<times;i++){//一共发送10次广播,每次等待2秒是否有回应 //广播发送服务器地址请求 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)){ memset(buffer,0,1024); count=recvfrom(sock,buffer,1024,0,(struct sockaddr*)&from_addr,&from_len);//from_addr为服务器端地址 strcpy((buffer+strlen(buffer)),"\0"); printf("recvmsg is %s ,The length of recvmsg is %d\n",buffer,strlen(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)); } } break; } } } return; }
注意:
1、程序是死循环完成接收或者发送广播包
2、程序没有内存泄漏问题
3、程序没有接收乱码的问题服务器端运行效果:
=====================================Send Broadcast========================================
recvmsg is IP_FOUND_ACK ,The length of recvmsg is 12
found server IP is:10.10.2.59
Server Port:9999
=====================================Send Broadcast========================================
recvmsg is IP_FOUND_ACK ,The length of recvmsg is 12
found server IP is:10.10.2.59
Server Port:9999
客户端运行效果:
=============================Recv Broadcast===================================
ret=1
Client IP is 10.10.2.59
Client Send Port:33784
=============================Recv Broadcast===================================
ret=1
Client IP is 10.10.2.155
Client Send Port:38542
相关文章推荐
- 嵌入式Linux下Gstreamer编程示例
- 在linux环境下 通过示例对目录的三种权限进行幽默解读
- 如何使用eclipse进行嵌入式Linux的开发
- linux配置samba服务器和windows进行数据交互
- 如何使用eclipse进行嵌入式Linux的开发
- 使用eclipse进行调试嵌入式Linux程序
- 嵌入式Linux web配置示例
- Django 使用Ajax进行前后台交互的示例讲解
- 嵌入式 linux下date命令详解以及如何在Makefile中定义宏并在c中进行使用来定义软件版本号
- 在linux 内核中做开关变量的三种方法—— 利用proc 、sys文件系统,字符设备等与内核进行交互
- linux中直接进行系统调用和通过C库调用的示例
- 嵌入式linux项目开发(一)——web数据交互
- C#与IronPython脚本进行数据交互示例
- 在进行嵌入式开发之前,首先要建立一个交叉编译环境,这是一套编译器、连接器和libc库等组成的开发环境。文章通过一个具体的例子说明了这些嵌入式交叉编译开发工具的制作过程。 随着消费类电子产品的大量开发和应用和Linux操作系统的不断健壮和强大,嵌入式系统越来
- 【嵌入式Linux学习七步曲之第二篇 交叉开发环境】U-boot和Windows TFTP server交互,socket recv error 10060
- 嵌入式linux项目开发(一)——web数据交互
- 如何使用eclipse进行嵌入式Linux的开发
- Linux下Java 通过JNI native与C进行交互的方法实现示例
- 利用广播进行两个Activity之间的交互
- C#与IronPython脚本进行数据交互示例