赞
踩
UDP的通信搭建流程:
因为UDP没有分服务器或者是客户端,所以最好两个端都绑定一下
-----------------------UDP单播的搭建步骤------------------------ 1.创建通信socket int udpfd=socket(AF_INET,SOCK_DGRAM,0); if(udpfd < 0) { perror("creat udp fail\n"); return -1; } 2.绑定 bind 3.数据的交互 //数据的发送 ssize_t sendto(int sockfd, //文件描述符 const void *buf, //数据的缓存区 size_t len, //数据大小 int flags,//发送与接收的属性 默认:0 const struct sockaddr *dest_addr,//接收者的IP与端口号信息 socklen_t addrlen);//信息结构体的大小 //数据的接收 ssize_t recvfrom(int sockfd, //UDP 通信描述符 void *buf,//接收后的数据缓存区 size_t len,//接收的数据大小 int flags,//默认为 0 即可 struct sockaddr *src_addr, //目标的IP地址信息 socklen_t *addrlen); //成功接收对方的IP地址信息的大小 4.关闭通信
----------------------------UDP的组播通信-------------------------------------
什么组播??
加入到一个组别里面,当我们发送数据到该组别中,所有进入该组的,UDPsocket 都可以接收到信息。
组播报文的目的地址使用D类IP地址
D 类 224.0.0.0 到 239.255.255.255 -》 该地址段的IP 是用来做组播地址的
UDP的组播设置: 1.创建通信UDP socket 2.设置该udp socket 加入到一个组播地址中 (setsockopt 设置网络通信对象的属性) 组播的设置: setsockopt 的选项: LEV 属性 IPPROTO_IP IP_ADD_MEMBERSHIP · 加入多播组 ip_mreq{} ************************* struct ip_mreq zu={0}; zu.imr_multiaddr.s_addr = inet_addr("224.10.10.2"); //设置组播地址 zu.imr_interface.s_addr = inet_addr("0.0.0.0"); //让系统自己检测IP int ret = setsockopt(socketfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&zu,sizeof(zu)); ************************* //组播地址结构体 struct ip_mreq { struct in_addr imr_multiaddr; //组播的IP地址 struct in_addr imr_interface; //自己的本地IP地址 }; /* Internet address. */ struct in_addr { __be32 s_addr; }; __be32 -》32位的整形数据 3.绑定自己的IP地址与端口号 4.接收组播数据 5.关闭通信
-------------------------------UDP的广播设置------------------------------
通过ifcofig查看当前网络的广播地址
inet 192.168.13.4 netmask 255.255.255.0 broadcast 192.168.13.255
(IP地址) (子网掩码) (当前网段的广播地址)
使用广播模式需要注意:不要经常发送广播数据,会造成网络风暴,让网络瘫痪。
1.创建UDP 的通信对象 2.开启广播功能 (setsockopt 设置广播属性) 属性设置如下: LEV 属性 SOL_SOCKET SO_BROADCAST · · 允许发送广播数据报 · int 设置如下: int on=1; //开启 setsockopt(socketfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on)); 注意: on = 1开启 on = 0关闭 3.设置该网段的广播地址并发送sendto 例如:192.168.13.XXX 广播地址为:192.168.13.255 struct sockaddr_in addr; addr.sin_addr.s_addr = inet_addr("192.168.13.255"); 4.关闭通信
注意事项:广播与组播的接收端的IP地址绑定的时候都需要填写为 “0.0.0.0” 否则会无法接收到数据!!!
//single_send.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> const int port = 12580; const char *ip = "10.8.6.90" int main() { //create socket int st = socket(AF_INET, SOCK_DGRAM, 0); if (st == -1) { printf("create socket failed ! error message :%s\n", strerror(errno)); return -1; } struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); //设置结构sockaddr_in类型是TCP/IP addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = inet_addr(ip); char buf[1024] = { 0 }; while (1) { //read read(STDIN_FILENO, buf, sizeof(buf)); if (sendto(st, buf, strlen(buf), 0, (struct sockaddr *) &addr, sizeof(addr)) == -1) { printf("sendto failed ! error message :%s\n", strerror(errno)); break; } memset(buf,0,sizeof(buf)); } close(st); return 0; }
//single_recv.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> const int port = 12580; int main() { int st=socket(AF_INET,SOCK_DGRAM,0); if(st==-1) { printf("open socket failed ! error message : %s\n",strerror(errno)); return -1; } int port=atoi(port); //defien ip address strcut struct sockaddr_in addr; //define addr type addr.sin_family=AF_INET; addr.sin_port=htons(port); addr.sin_addr.s_addr=htonl(INADDR_ANY); //bind port if(bind(st,(struct sockaddr *)&addr,sizeof(addr))==-1) { printf("bind IP failed ! error message : %s\n",strerror(errno)); goto END; } char buf[1024]={0}; struct sockaddr_in client_addr; socklen_t addrlen=sizeof(client_addr); while(1) { memset(&client_addr,0,sizeof(client_addr)); if(recvfrom(st,buf,sizeof(buf),0,(struct sockaddr *)&client_addr,&addrlen)==-1) { printf("recvfrom failed ! error message : %s\n",strerror(errno)); goto END; }else { printf("from %s:%s\n",inet_ntoa(client_addr.sin_addr),buf); } memset(buf,0,sizeof(buf)); } END:close(st); return 0; }
//group_send.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main(int arg, char * args[]) { //1.创建UDP socket int st = socket(AF_INET, SOCK_DGRAM, 0); if (st == -1) { printf("create socket failed ! error message :%s\n", strerror(errno)); return -1; } //设置组播IP地址 struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); //设置结构sockaddr_in类型是TCP/IP addr.sin_family = AF_INET; addr.sin_port = htons(8888); addr.sin_addr.s_addr = inet_addr("224.10.10.2"); //设置为组播地址 char buf[1024] = {0}; while (1) { //发送数据到组播地址中 scanf("%s",buf); sendto(st, buf, strlen(buf), 0, (struct sockaddr *)&addr,sizeof(addr)); memset(buf,0,sizeof(buf)); } close(st); return 0; }
//group_recv.c #include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> int main(int argc,char *argv[]) { // 1.创建udp通信socket int socketfd = socket(AF_INET,SOCK_DGRAM,0); if(socketfd < 0 ) { perror("creat socket fail\n"); return -1; } //3.加入组播 struct ip_mreq zu={0}; zu.imr_multiaddr.s_addr = inet_addr("224.10.10.2"); //设置组播地址 zu.imr_interface.s_addr = inet_addr("0.0.0.0"); //让系统自己检测IP int ret = setsockopt(socketfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&zu,sizeof(zu)); if(ret < 0) { perror("setsockopt fail\n"); return -1; } //2.设置UDP的地址并绑定 struct sockaddr_in seraddr={0}; seraddr.sin_family = AF_INET; //使用IPv4协议 seraddr.sin_port = htons(8888); //网络通信都使用大端格式 seraddr.sin_addr.s_addr = inet_addr("0.0.0.0"); ret = bind(socketfd,(struct sockaddr*)&seraddr,sizeof(seraddr)); if(ret < 0) { perror("bind fail:"); return -1; } //接收客户发送过来的数据 while(1) { char buf[1024]={0}; struct sockaddr_in src_addr={0}; //定义一个缓冲区 存放对方的IP地址信息 int len = sizeof (struct sockaddr_in); recvfrom(socketfd,buf,1024,0,(struct sockaddr *)&src_addr,&len); printf("buf=%s\n",buf); } close(socketfd); return -1; }
//UDP 发送广播信息 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main() { //1.创建UDP socket int st = socket(AF_INET, SOCK_DGRAM, 0); if (st == -1) { printf("create socket failed ! error message :%s\n", strerror(errno)); return -1; } //2.开启发送广播数据功能 int on=1; //开启 int ret = setsockopt(st,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on)); if(ret < 0) { perror("setsockopt fail\n"); return -1; } //3.设置该网段的广播地址 struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(8888); addr.sin_addr.s_addr = inet_addr("10.8.6.255"); //设置为广播地址 //4.发送广播数据 while(1) { sendto(st,"hello", strlen("hello"), 0, (struct sockaddr *)&addr,sizeof(addr)); sleep(1); } //5.关闭网络通信 close(st); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。