一、了解UDP通信协议
UDP(User Datagram Protocol,用户数据报协议)是一种无连接、不可靠的传输层协议。它提供简单的数据传输服务,无需在发送方和接收方之间建立连接。每个UDP数据报都是一个独立的信息,包括完整的源地址和目的地址,它在网络上以任何可能的路径传往目的地。由于UDP不保证数据是否完全的送达、到达目的地的时间以及内容的正确性,因此它被认为是一种不可靠的协议。
二、UDP协议的特点
无连接性:
UDP在发送数据之前不需要建立连接,即无需经历“三次握手”等连接建立过程。这减少了开销和发送数据之前的时延,使得UDP具有更高的传输效率。
不可靠性:
UDP使用“尽最大努力交付”的方式,即不保证可靠交付。它不提供重传机制和顺序控制机制,发出的数据包一旦发生丢失就无法恢复,也无法保证接收方接收到数据的顺序一定是发送方发送的顺序。
面向报文:
UDP是面向报文的传输层协议。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。
首部开销小:
UDP的首部开销只有8个字节,比TCP的20个字节的首部要短。这使得UDP在传输效率上具有一定的优势。
无需拥塞控制:
UDP不支持拥塞控制,这可能导致网络拥堵。但正因为没有拥塞控制,UDP的传输速度相对于TCP来说更快,适用于实时性要求高的场景。
支持多播和广播:
UDP允许将数据包发送给指定的多个主机,也允许将数据包广播给同一网络的所有主机。这种特性使得UDP在多播和广播应用中具有广泛的应用。
应用场景广泛:
UDP主要用于实时性要求高,但对数据可靠性要求不高的场景,例如实时视频、音频传输、在线游戏等。在这些场景中,UDP的低延迟和高效率特性得到了充分的利用。
速度快,较安全:
与TCP协议相比,UDP协议排除了信息可靠传递机制,减少了TCP协议中提供数据包分组、组装和排序的过程需要的时间消耗。此外,UDP是一个无状态的传输协议,所以在传递数据时非常快。并且,没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些。
三、UDP通信原理
在Android中,UDP通信主要基于java.net.DatagramSocket和java.net.DatagramPacket这两个类实现。
DatagramSocket:用于创建UDP套接字,指定本地端口号。通过该对象,可以发送和接收UDP数据报。
DatagramPacket:用于表示一个UDP数据报,包含要发送或接收的数据、数据长度、目标地址和端口号等信息
四、UDP通信步骤
通信部分得分为两步,一个是服务端,一个是客户端
服务端步骤:
1.创建套接字:
1.使用socket()函数创建一个UDP套接字,指定地址族(如AF_INET表示IPv4)和套接字类型(SOCK_DGRAM表示UDP)。
2.函数原型:
int socket(int domain, int type, int protocol);
2.绑定IP和端口(可选):
1.如果服务端需要监听特定端口,则使用bind()函数将套接字与本地IP地址和端口号绑定。
2.函数原型:
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
3.接收数据:
使用recvfrom()函数从套接字接收数据。由于UDP是无连接的,所以每次接收数据都需要指定来源地址和端口。
函数原型:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
4.发送数据(可选):
1.如果服务端需要主动发送数据,使用*sendto()*函数。
2.函数原型:
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
5.关闭套接字:
1.使用close()函数关闭套接字。
客户端步骤:
1.创建套接字:
与服务端相同,使用socket()函数创建一个UDP套接字。
2.发送数据:
使用sendto()函数向服务端发送数据,需要指定服务端的IP地址和端口号。
3.接收数据(可选):
如果客户端需要接收服务端的响应,使用recvfrom()函数。
4.关闭套接字:
使用close()函数关闭套接字。