一.UDP头部信息:
特性:无连接,不可靠,面向数据报.
协议字段:
-
16位源端口号,16位目的端口号:描述数据从哪个进程来,到哪个进程去.
-
16位校验和: 二进制反码求和算法(检验接收的数据与发送的数据是否完全一致)
-
16位数据报长度(UDP首部+UDP数据长度):
-
UDP数据包最大长度(包含头部)不能超过64K 2^16
-
UDP协议sendto接口发送的数据长度不能超过64K-8,UDP协议对于sendto发送的数据直接进行封装头部,发送出去.若数据长度大于64K-8,则需要用户在应用层进行分包操作.UDP并不保证可靠,也不保证包序,因此分包以后还需要在应用层进行包序管理
-
决定了UDP数据只能整条收发
应用: 不能应用于安全性要求高的传输,但是因为报头短,并且不需要保证可靠传输,因此传输速度快,因此应用于实时性高的场景.
在传输层基于UDP实现的应用层协议: DHCP协议(动态地址分配协议),DNS(域名解析协议)
-
二.UDP网络编程
服务端: 1.创建套接字 2. 绑定地址信息 3.接收数据 4.发送数据 5.关闭套接字
客户端: 1. 创建套接字 2.发送数据 3.接收数据 4.关闭套接字
创建套接字:
int socket(int domain, int type, int protocol);
domain:地址域 : AF_INET ipv4
type:套接字类型
SOCK_STREAM:流式套接字 对应的协议:TCP
SOCK_AGRAM:数据报套接字 对应的协议:UDP
protocol:
0:套接字类型默认协议
IPPROTO_TCP : 6
IPPROTO_UDP : 17
返回值:文件描述符:套接字操作句柄
绑定地址信息:
int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
sockfd:操作句柄:套接字描述符
struct sockaddr_in{
short int sin_family; //指代协议簇,AF_INET(socket编程中)
unsigned short int sin_port; //存储端口号(使用网络字节序)
struct in_addr sin_addr; //存储ip地址,使用 in_addr 数据结构
unsigned char sin_zero[8]; //是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节
}
struct in_addr{
unsigned long s_addr;
}
addrlen:struct sockaddr 的结构体大小
发送及接收数据:
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
关闭套接字:
int close(sockfd);
地址转换接口:
htons/htonl:主机字节序到网络字节序的整数转换 short-16/int-32
ntohs/ntohl:网络字节序到主机字节序的整数装换 short-16/int-32
int_addr_t inet_addr(const char* cp):点分十进制字符串IP地址到网络字节序整数IP地址的转换
三.UDP怎么实现可靠
如果要用udp实现可靠,那就必须要解决两个问题:丢包和包的顺序(包序)问题:在应用层实现
给数据包进行编号,按照包的顺序进行接收并存储
接收端收到数据包后,发送确认信息给发送端,发送端收到数据后再继续发送下一个包.如果接收端接收的数据包编号不是预期的编号,则要求发送端重新发送 (实现确认机制与重传机制)
已经实现udp可靠传输的协议:
RUDP:可靠数据报传输协议
RTP:实时传输协议,为数据提供了具有实时性的端对端传送服务
UDT:互联网传输协议,主要目的是支持高速广域网上的海量数据传输