UDP是无连接的,即发送数据之前不需要建立连接,它尽最大努力交付,即不保证可靠交付,在一些要求实时性的通信中多有用到如游戏,视频等,UDP是面向报文的,有别于tcp的一对一通信,udp支持一对一、一对多、多对一和多对多的交互通信等。 一、udp通信用到的相关函数解析 int socket(int domain, int type, int protocol); 功能:创建socket对象 type:SOCK_DGRAM 数据报协议 UDP int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen); 功能:绑定socket和通信地址 sockfd:socket描述符 addr:地址结构体指针,实际传递的是 sockaddr_un或者sockaddr_in 结构体指针,需要把它们统一转换为sockaddr*类型。具体sockaddr_in结构体在socket的本地通信博文中有提到,这里不再赘述。 UDP专属的数据发送接收函数: ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen); 功能:UDP协议发送数据 sockfd:socket描述符 buf:待发送数据内存首地址 len:待发送数据的字节数 flags:是否阻塞 一般写0阻塞即可 dest_addr:通信目标的地址 addrlen:地址结构体的字节数 返回值:成功发送的字节数,0表示通信关闭,-1表示出现错误 ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen); 功能:UDP协议接收数据 sockfd:socket描述符 buf:存储接收数据的缓冲区内存首地址 len:缓冲区的字节数 flags:是否阻塞 一般写0阻塞即可 src_addr:用于存储发送者的地址 addrlen:既是输入,也是输出,既告诉函数当前src_addr结构体的字节数,同时也能实际接收到发送者的地址结构体字节数。 返回值:成功接收到的字节数,0表示通信关闭,-1表示出现错误。 二、udp通信的编程模型 基于UDP通信协议的网络通信编程模型: 接收端 发送端 创建socket 创建socket 准备通信地址 准备通信地址 绑定 ... 接收请求 发送请求 响应请求 接收响应 关闭socket 关闭socket 三、dup通信编程示例 服务器端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> typedef struct sockaddr* SP; int main(int argc,const char* argv[]) { //创建socket int sockfd = socket(AF_INET,SOCK_DGRAM,0); if(0 > sockfd) { perror("socket"); return EXIT_FAILURE; } //准备本机通信地址 struct sockaddr_in srv_addr = {},cli_addr = {}; srv_addr.sin_family = AF_INET; srv_addr.sin_port = htons(7788); //这里的“xxx.xx.xx.xx”写本机的ip地址,可以用ifconfig命令查看,windows可以用ipconfig查看 srv_addr.sin_addr.s_addr = inet_addr("xxx.xx.xx.xx"); socklen_t addrlen = sizeof(srv_addr); //绑定 if(bind(sockfd,(SP)&srv_addr,addrlen)) { perror("bind"); return EXIT_FAILURE; } char buf[4096] = {}; size_t buf_size = sizeof(buf); for(;;) { //接收数据和对方的地址 int ret = recvfrom(sockfd,buf,buf_size,0,(SP)&cli_addr,&addrlen); if(0 >= ret) { printf("网络异常,通信结束!"); close(sockfd); return EXIT_FAILURE; } printf("from %s recv:[%s] bits:%d\n", inet_ntoa(cli_addr.sin_addr),buf,ret); //返回响应 strcat(buf,"from udpS"); ret = sendto(sockfd,buf,strlen(buf)+1,0,(SP)&cli_addr,addrlen); if(0 >= ret) { printf("对方网络异常!\n"); } } } 客户端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> typedef struct sockaddr* SP; int main(int argc,const char* argv[]) { //创建socket int sockfd = socket(AF_INET,SOCK_DGRAM,0); if(0 > sockfd) { perror("socket"); return EXIT_FAILURE; } //准备服务器通信地址 struct sockaddr_in srv_addr = {}; srv_addr.sin_family = AF_INET; srv_addr.sin_port = htons(7788); srv_addr.sin_addr.s_addr = inet_addr("xx.xx.xxx.xxx");//这里写需要通信的ip地址 socklen_t addrlen = sizeof(srv_addr); char buf[4096] = {}; size_t buf_size = sizeof(buf); for(;;) { printf(">>>"); scanf("%s",buf); if(0 == strcmp(buf,"quit")) { printf("结束通信!\n"); close(sockfd); return EXIT_SUCCESS; } int ret = sendto(sockfd,buf,strlen(buf)+1,0,(SP)&srv_addr,addrlen); if(0 >= ret) { printf("网络异常!\n"); close(sockfd); return EXIT_FAILURE; } //接收数据和对方的地址 ret = recvfrom(sockfd,buf,buf_size,0,(SP)&srv_addr,&addrlen); if(0 >= ret) { printf("网络异常,通信结束!"); close(sockfd); return EXIT_FAILURE; } printf("from %s recv:[%s] bits:%d\n", inet_ntoa(srv_addr.sin_addr),buf,ret); } }
标签:udp,addr,int,Linux,sockfd,include,buf,socket From: https://www.cnblogs.com/kn-zheng/p/17560402.html