赞
踩
UDP(User Datagram Protocol)用户数据报协议是一种非面向连接的协议,这种协议并不能保证
我们的网络程序的连接是可靠的,而TCP是面向连接的协议,提供可靠服务。但是相对于TCP而言,UDP实时性较好,适用于高速传输和实时性要求较高的通信中。
UDP服务器端实现步骤:
1、创建socket,选用SOCK_DGRAM(UDP)
2、bind绑定ip地址和socket
3、使用recvfrom()函数接收客户端数据
(4、使用sendto函数发送数据)
UDP客户端实现步骤:
1、创建socket,选用SOCK_DGRAM(UDP)
2、定义sockaddr_in 结构体变量并初始化
3、使用recvfrom()函数接收客户端数据
相关函数API介绍
int socket(int domain, int type, int protocol);
参数:
domain:域。
AF_INET/PF_INET: 网际协议
AF_UNIX/PF_UNIX:本地协议,可写成AF_LOCAL/PF_LOCAL
type:类型
SOCK_STREAM:流式套接字
SOCK_DGRAM:数据报套接字
protocol:协议
一般为0
返回值:
成功:待连接套接字;
失败:-1
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 参数: sockfd:待连接套接字 addr:包含本地地址(IP+PORT)的通用地址结构体的指针 addrlen:地址结构体大小 返回值: 成功:0; 失败:-1 备注,通用地址结构体的定义: struct sockaddr { sa_family_t sa_family; char sa_data[14]; }; 特殊地址结构体 —— IPv4地址结构体: struct sockaddr_in { u_short sin_family; // 地址族 u_short sin_port; // 端口 struct in_addr sin_addr; // IPV4地址 char sin_zero[8]; }; struct in_addr { in_addr_t s_addr; // 无符号32位网络地址 }; 特殊地址结构体 —— IPv6地址结构体: struct sockaddr_in6 { u_short sin6_family; // 地址族 __be16 sin6_port; // 端口 __be32 sin6_flowinfo; // 流信息 struct in6_addr sin6_addr; // IPv6地址 __u32 sin6_scope_id; }; 特殊地址结构体 ——UNIX域地址结构体: struct sockaddr_un { u_short sun_family; // 地址族 char sun_path[108]; // 套接字文件路径 };
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
接口声明:从UDP套接字接收数据
参数:
sockfd:UDP套接字
buf:储存数据缓冲区
len:缓冲区大小
flags:接收标志,与函数send的flags完全一致
src_addr:对端网络地址
addrlen:地址长度
返回值:
成功:已接收字节数
失败:-1
/* 基于UDP实现的服务器 author:zx date:2023-3-10 创建服务步骤: 1、创建socket,选用SOCK_DGRAM(UDP) 2、bind绑定ip地址和socket 3、使用recvfrom()函数接收客户端数据 */ #include <stdio.h> #include <sys/socket.h> #include <string.h> #include <sys/types.h> #include <arpa/inet.h> #include <unistd.h> int main() { int sockfd; int retval; if(sockfd == -1) { printf("sock error\n"); return -1; } serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr =htonl(INADDR_ANY);//任意地址 serverAddr.sin_port = htons(6565); retval = bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); if(retval < 0) { printf("bind error\n"); return -1; } { printf("[UDP server]recv form client:%s\n", buf); } else { printf("[UDP server] recv error!\n"); break; } } close(sockfd); return 0; }
/* 基于UDP实现的客户端 author:zx date:2023-3-10 创建服务步骤: 1、创建socket,选用SOCK_DGRAM(UDP) 2、定义sockaddr_in 结构体变量并初始化 3、使用recvfrom()函数接收客户端数据 */ #include <stdio.h> #include <sys/socket.h> #include <string.h> #include <sys/types.h> #include <arpa/inet.h> #include <unistd.h> int main() { int sockfd; int retval; struct sockaddr_in clientAddr; sockfd = socket(AF_INET, SOCK_DGRAM, 0);//UDP if(sockfd == -1) { printf("sock error\n"); return -1; } clientAddr.sin_family = AF_INET; clientAddr.sin_addr.s_addr = htonl(INADDR_ANY); clientAddr.sin_port = htons(6565); char buf[1024] = "hello udp server"; socklen_t len = sizeof(clientAddr); int count = 0; while(1) { sprintf(buf, "hello udp server,count:%d", count++); retval = sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&clientAddr, len); if(retval > 0) { printf("[UDP client]send to server:%s\n", buf); } else { printf("[UDP client] send error!\n"); break; } sleep(2); } close(sockfd); return 0; }
客户端
服务器端
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。