下面是自我测试
- | udp编程步骤是什么
- | UDP服务器端/客户端发送数据是什么函数
- | UDP服务器端/客户端接收数据是什么函数
1. UDP编程框架
- UDP是面向非连接的协议,不与对方建立连接,直接把我要发的数据报发给对方
- UDP适用于一次传输数据量很少、对可靠性要求不高的或对实时性要求高的应用场景(物联网)
- UDP无需建立类如三次握手的连接,而使得通信效率很高
UDP通信框架 UDP编程不需要listen请求连接与accept连接,在bind网络地址后,就可以直接UDP通信了 |
---|
1.2 sendto函数 //socket,bind参考TCP中的介绍
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); |
---|
功能:进行一次UDP发送 注意:由于UDP通信的特点是无连接的,所以每次发送都要写网络地址结构体,确保发送到哪个主机哪个进程 |
参数1:sockfd:socket描述符,socket获得 |
参数2:发送的数据 |
参数3:发送多少字节 |
参数4:flags填0即可 |
第五个参数dest_addr:网络地址结构体的地址 |
第六个参数addrlen:网络地址结构体的长度 |
返回值: 成功:返回发送成功的数据长度 失败: -1 |
1.3 recvfrom函数
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); |
---|
功能:UDP接收函数 |
参数1:sockfd是socket描述符,通过socket获得 |
参数2:buf是接收缓冲区 |
参数3:l接收多少字节 |
参数4:flags填0即可 |
参数5:网络地址结构体地址,确定获取到数据是谁发出的 |
参数6:参数5的字节长度 |
返回值: 成功:返回接收成功的数据长度 失败: -1 |
ser.c实现接收cli.c的UDP数据 cli.c向ser.c发送UDP数据 =============================================================== * Copyright (C) 2020 All rights reserved. * * 文件名称:ser.c * 创 建 者:liujing * 创建日期:2020年07月26日 * 描 述: * * 更新日志: * ================================================================*/ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <strings.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> /* superset of previous */ #include <arpa/inet.h> void main() { //获取socket描述符 int socketid; //IPV4+UDP+协议默认 socketid = socket(AF_INET,SOCK_DGRAM,0); if(socketid < 0) { perror("\n>>socket error:\n"); } else { printf("\n>>socket success\n"); } //绑定自身服务器网络地址,让客户端连接192.168.43.69-5001这个网络地址 struct sockaddr_in socketaddr; socketaddr.sin_family = AF_INET; socketaddr.sin_port = 5001; if(1 == inet_pton(AF_INET,"192.168.43.69",&socketaddr.sin_addr)) { printf("\n>>inet_pton success\n"); } else { perror("\n>>inet_pton error:\n"); } int socketaddr_size = sizeof(socketaddr); if(0 == bind(socketid,(struct sockaddr *)&socketaddr,sizeof(socketaddr))) { printf("\n>>bind success\n"); } else { perror("\nbind error\n"); } //发送与接受 struct sockaddr_in src; //接收发送者的网络地址 int ret; char getbuf[32] = { 0}; //接收缓存 while(1) { //本机接受别人发来的UDP数据,参数用来接收对方的网络地址 ret = recvfrom(socketid,getbuf,32,0,(struct sockaddr*)&src,(socklen_t *)&socketaddr_size); printf("\nrecvfrom ok\n"); sleep(2); //打印 puts(getbuf); if(ret == 0) { printf("\nbreak;\n"); break; } } close(socketid); } =============================================================== * Copyright (C) 2020 All rights reserved. * * 文件名称:cli.c * 创 建 者:liujing * 创建日期:2020年07月26日 * 描 述: * * 更新日志: * ================================================================*/ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <strings.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> /* superset of previous */ #include <arpa/inet.h> void main() { //获取socket描述符 int socketid; //IPV4+UDP+协议默认 socketid = socket(AF_INET,SOCK_DGRAM,0); if(socketid < 0) { perror("\n>>socket error:\n"); } else { printf("\n>>socket success\n"); } //填写目标地址服务器网络地址 struct sockaddr_in socketaddr; socketaddr.sin_family = AF_INET; socketaddr.sin_port = 5001; if(1 == inet_pton(AF_INET,"192.168.43.69",&socketaddr.sin_addr)) { printf("\n>>inet_pton success\n"); } else { perror("\n>>inet_pton error:\n"); } int socketaddr_size = sizeof(socketaddr); //发送与接受 struct sockaddr_in src; int ret; char getbuf[32] = { 0}; while(1) { //由于客户端没有bind绑定自己的网络地址,所以不能接受服务器数据: //本机UDP发送"i am client",参数是目标网络地址 ret = sendto(socketid,"i am client",32,0,(struct sockaddr *)&socketaddr,(socklen_t)socketaddr_size); printf("\nsendto ok\n"); sleep(2); if(ret == 0) { printf("\nbreak;\n"); break; } } close(socketid); } =============================================================== 客户端1运行结果如下: farsight@ubuntu:~/Desktop$ ./cli >>socket success >>inet_pton success sendto ok sendto ok sendto ok sendto ok sendto ok sendto ok sendto ok ^C farsight@ubuntu:~/Desktop$ =============================================================== 服务器端运行结构如下: farsight@ubuntu:~/Desktop$ ./ser >>socket success >>inet_pton success >>bind success recvfrom ok i am client recvfrom ok i am client recvfrom ok i am client recvfrom ok i am client recvfrom ok i am client recvfrom ok i am client recvfrom ok i am client ===============================================================