UDP 广播机制
来源:互联网 发布:淘宝淘工作 兼职可信吗 编辑:程序博客网 时间:2024/05/20 01:34
UDP
1,简介
UDP 为用户数据包协议,它的头为8byte数据;分别为16bit源端口号,16bit目的端口号,16bit长度,16bit校验和;它为无连接,主要用于视频传输相关的应用;因为
客户比较关注实时性; 它不需像TCP 那样,在发送数据前需建立连接;
2,基于udp 广播的client server端实例:
client:#include <stdio.h>#include <sys/socket.h>#include <unistd.h>#include <string.h>#include <netinet/in.h>#include <arpa/inet.h>#include <linux/if.h>#include <sys/ioctl.h>#include <errno.h>#define DDPAI_FOUND "DDPAI_FOUND"#define DDPAI_FOUND_ACK "DDPAI_FOUND_ACK"#define IFNAME "wlan0"#define MCAST_PORT 8888int main(int argc, char **argv){ int socketFd = -1; int lRtn = -1; struct sockaddr_in destAddr; struct sockaddr_in sourAddr; /*创建数据报套接字*/ socketFd = socket(AF_INET,SOCK_DGRAM,0); if(socketFd < 0) { printf("socket error:%d\n",errno); return -1; } /*设置源地址为本地广播地址*/ bzero(&sourAddr,sizeof(struct sockaddr_in)); sourAddr.sin_family = AF_INET; sourAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST); sourAddr.sin_port = htons(MCAST_PORT); const int broadcastOpt = 1; /*设置套接字为广播类型*/ lRtn = setsockopt(socketFd,SOL_SOCKET,SO_BROADCAST,(char *)&broadcastOpt,sizeof(broadcastOpt)); if(lRtn < 0) { printf("set socket broadcast error:%d\n",errno); close(socketFd); return -1; } /*设置套接字 发送/接收缓冲区 属性*/ const int nSendBuf = 0; lRtn = setsockopt(socketFd,SOL_SOCKET,SO_SNDBUF,(char *)&nSendBuf,sizeof(int)); if(lRtn < 0) { close(socketFd); printf("setsockopt SO_SNDBUF error\n"); return -1; } const int nRcvBuf = 0; lRtn = setsockopt(socketFd,SOL_SOCKET,SO_RCVBUF,(char *)&nRcvBuf,sizeof(int)); if(lRtn < 0) { close(socketFd); printf("setsockopt SO_RCVBUF error\n"); return -1; } int lSize = sizeof(destAddr); fd_set rFdSet; struct timeval tv; sleep(1); int idx = 0; for(idx = 0; idx < 5; idx++) { lRtn = sendto(socketFd,DDPAI_FOUND,strlen(DDPAI_FOUND),0,(struct sockaddr *)&sourAddr,lSize); if(lRtn < 0) { printf("sendto error:%d\n",errno); close(socketFd); return -1; } printf("[client] send %d byte file ok \n",lRtn); } while(1) { FD_ZERO(&rFdSet); FD_SET(socketFd,&rFdSet); tv.tv_sec = 1; tv.tv_usec = 0; printf("[client] %s %d\n",__func__,__LINE__); lRtn = select(socketFd+1,&rFdSet,NULL,NULL,&tv); if(lRtn < 0) { printf("select error\n"); close(socketFd); return -1; } else if(lRtn == 0) { usleep(100000); printf("timeout\n"); continue; } else { if(FD_ISSET(socketFd,&rFdSet)) { char msg[128] = {0x00}; lRtn = recvfrom(socketFd,msg,128,0,(struct sockaddr*)&destAddr,(socklen_t *)&lSize); if(lRtn <= 0) { printf("recvfrom error\n"); } else { printf("recv %d byte data:%s\n",lRtn,msg); if(NULL != strstr(msg,DDPAI_FOUND_ACK)) { printf("server ip:%s msg:%s\n",inet_ntoa(destAddr.sin_addr),msg); } } } usleep(500000); } } close(socketFd); return 0;}
server:#include <stdio.h>#include <stdlib.h>#include <sys/socket.h>#include <unistd.h>#include <string.h>#include <netinet/in.h>#include <arpa/inet.h>#include <linux/if.h>#include <sys/ioctl.h>#include "errno.h"#define DDPAI_FOUND "DDPAI_FOUND"#define DDPAI_FOUND_ACK "DDPAI_FOUND_ACK"#define MCAST_PORT 8888#define IFNAME "wlan0"#define IPADDR_SIZE 32struct interface_info{ char ip_addr[IPADDR_SIZE]; char broad_addr[IPADDR_SIZE]; char mask_addr[IPADDR_SIZE]; char mac_addr[IPADDR_SIZE];};void freeMem(void *pFree){ free(pFree); pFree = NULL;}int getLocalInterfaceInfo(struct interface_info *if_info){ #define INET_ADDRSRLEN 128 int sockFd = -1; int lRtn = -1; struct ifreq ifr; struct sockaddr_in *addr; if((sockFd = socket(AF_INET,SOCK_DGRAM,0)) < 0) { printf("%s create socket error\n",__func__); return -1; } strncpy(&ifr.ifr_name,IFNAME,strlen(IFNAME)); /*获取ip address*/ lRtn = ioctl(sockFd,SIOCGIFADDR,&ifr); if(lRtn < 0) { printf("ioctl SIOCGIFADDR error:%d\n",errno); close(sockFd); return -1; } /*获取广播地址*/ addr = (struct sockaddr_in *)&(ifr.ifr_addr); sprintf(if_info->ip_addr,"%s",inet_ntoa(addr->sin_addr)); printf("ipaddr:%s\n",if_info->ip_addr); lRtn = ioctl(sockFd,SIOCGIFBRDADDR,&ifr); if(lRtn < 0) { printf("ioctl SIOCGIFBRDADDR error:%d\n",errno); close(sockFd); return -1; } /*获取子网掩码*/ addr = (struct sockaddr_in *)&(ifr.ifr_broadaddr); sprintf(if_info->broad_addr,"%s",inet_ntoa(addr->sin_addr)); printf("broad_addr:%s\n",if_info->broad_addr); lRtn = ioctl(sockFd,SIOCGIFNETMASK,&ifr); if(lRtn < 0) { printf("ioctl SIOCGIFNETMASK error:%d\n",errno); close(sockFd); return -1; } /*获取MAC地址*/ addr = (struct sockaddr_in *)&(ifr.ifr_addr); sprintf(if_info->mask_addr,"%s",inet_ntoa(addr->sin_addr)); printf("mask_addr:%s\n",if_info->mask_addr); lRtn = ioctl(sockFd,SIOCGIFHWADDR,&ifr); if(lRtn < 0) { printf("ioctl SIOCGIFHWADDR error:%d\n",errno); close(sockFd); return -1; } unsigned char *hw = (unsigned char *)ifr.ifr_hwaddr.sa_data; sprintf(if_info->mac_addr,"%2x:%2x:%2x:%2x:%2x:%2x", hw[0],hw[1],hw[2],hw[3],hw[4],hw[5]); printf("macAddr:%s\n",if_info->mac_addr); close(sockFd); return 0; }int main(int argc, char **argv){#define BUS_SIZE 64 int socketFd = -1; int lRtn = -1; int lSize = 0; char buf[BUS_SIZE] = {0x00}; fd_set rFdSet; struct timeval tv; struct sockaddr_in destAddr; /*远端发送广播包地址*/ struct sockaddr_in sourAddr; /*绑定本地地址*/ struct interface_info *if_info; /* * 通用socket地址: * struct sockaddr * { * sa_family_t sa_family; 地址族类型 * char sa_data[14]; * } * 协议族 地址族 描述 * PF_UNIX AF_UNIX UNIX本地域协议族 * PF_INET AF_INET TCP/IPv4协议族 * PF_INET6 AF_INET6 TCP/IPv6协议族 */ if_info = (struct interface_info *)malloc(sizeof(struct interface_info)); if(NULL == if_info) { printf("malloc error\n"); return -1; } /*绑定本地地址*/ bzero(&sourAddr,sizeof(struct sockaddr_in)); sourAddr.sin_family = AF_INET; sourAddr.sin_addr.s_addr = htonl(INADDR_ANY); sourAddr.sin_port = htons(MCAST_PORT); /*创建数据报套接字*/ socketFd = socket(AF_INET,SOCK_DGRAM,0); if(socketFd < 0) { printf("socket error:%d\n",errno); freeMem(if_info); return -1; } const int broadcastOpt = 1; /*设置套接字为广播类型*/ lRtn = setsockopt(socketFd,SOL_SOCKET,SO_BROADCAST,(char *)&broadcastOpt,sizeof(broadcastOpt)); if(lRtn < 0) { printf("set socket broadcast error:%d\n",errno); close(socketFd); freeMem(if_info); return -1; } /* 设置套接字发送缓冲区大小为2K */ const int nSendBuf = 2*1024; lRtn = setsockopt(socketFd,SOL_SOCKET,SO_SNDBUF,(char *)&nSendBuf,sizeof(int)); if(lRtn < 0) { close(socketFd); freeMem(if_info); printf("setsockopt SO_SNDBUF error\n"); return -1; } /*设置套接字接收缓冲区大小为2K*/ const int nRcvBuf = 2*1024; lRtn = setsockopt(socketFd,SOL_SOCKET,SO_RCVBUF,(char *)&nRcvBuf,sizeof(int)); if(lRtn < 0) { close(socketFd); freeMem(if_info); printf("setsockopt SO_RCVBUF error\n"); return -1; } /*绑定套接字*/ lRtn = bind(socketFd,(struct sockaddr *)&sourAddr,sizeof(struct sockaddr_in)); if(lRtn < 0) { printf("bind error :%d\n",errno); close(socketFd); freeMem(if_info); return -1; } // getLocalInterfaceInfo(if_info); lSize = sizeof(destAddr); tv.tv_sec = 1; tv.tv_usec = 0; printf("[server] start recv data\n"); while(1) { FD_ZERO(&rFdSet); FD_SET(socketFd,&rFdSet); /*监听socketFd*/ lRtn = select(socketFd+1,&rFdSet,NULL,NULL,&tv); if(lRtn < 0) { printf("select error\n"); close(socketFd); freeMem(if_info); return -1; } else if(lRtn == 0) { usleep(100000); continue; } else { if(FD_ISSET(socketFd,&rFdSet)) { char msg[128] = {0x00}; lRtn = recvfrom(socketFd,msg,128,0,(struct sockaddr*)&destAddr,(socklen_t *)&lSize); if(lRtn <= 0) { printf("recvfrom error\n"); } else { printf("recv %d byte data:%s\n",lRtn,msg); if(NULL != strstr(msg,DDPAI_FOUND)) { // memcpy(buf,DDPAI_FOUND_ACK,strlen(DDPAI_FOUND_ACK)+1); // sprintf(buf,"%s:%s",DDPAI_FOUND_ACK,if_info->ip_addr); printf("[server] peer_ip:%s\n",inet_ntoa(destAddr.sin_addr)); lRtn = sendto(socketFd,DDPAI_FOUND_ACK,strlen(DDPAI_FOUND_ACK),0,(struct sockaddr *)&destAddr,(socklen_t)lSize); if(lRtn < 0) { printf("sendto error:%d\n",errno); freeMem(if_info); close(socketFd); return -1; } } } } usleep(500000); } } close(socketFd); freeMem(if_info); return 0;}
#1 需创建SOCK_DGRAM
#2 设置socket为广播属性SO_BROADCAST
#2 sendto /rcvfrom 绑定的地址 ,传入的参数
仅供参考,相互学习,有什么错误的地方以及优化的地方请指出;
0 0
- UDP 广播机制
- UDP广播
- UDP广播
- udp广播
- UDP广播
- UDP广播
- UDP广播
- UDP 广播
- UDP广播
- UDP广播
- UDP广播
- udp广播
- udp广播
- UDP广播
- UDP广播
- UDP广播
- udp广播
- iOS- 移动端Socket UDP协议广播机制的实现
- Server 2012 Datacenter操作系统远程桌面启用要点
- 项目合作遇到的问题及解决办法
- WINdows小技巧
- ansible的安装与使用
- spring 监听器 IntrospectorCleanupListener简介
- UDP 广播机制
- 获取memcache缓存下所有的键值对信息
- Android 进程常驻(1)----开篇
- Ubuntu 测试android真机 lsusb命令出现:????????????no permissions(解决办法)
- git rebase和merge 区别和应用场景
- 中文分词插件SCWS-1.2.3 在Linux环境的安装说明(包括php扩展)
- 求出二维数组中m*n的鞍点
- JDBC连接数据库的几个步骤
- 安卓中不同Activity之间的传值问题用Intent