NIO与Socket笔记 :实现Socket 通信[ 四 ]

基于UDP的Socket通信

UDP (User Datagram Protocol,用户数据报协议)是一种面向无连接的传输层协议,提供不可靠的信息传送服务 。

无连接是指通信时服务端与客户端不需要建立连接,直接把数据包从一端发送到另 一端,对方获取数据包再进行数据的处理 。

UDP 是“不可靠的”,是指该协议在网络环境不好的情况下,会丢失数据包,因为没有数据包重传的功能,另外它也不提供对数据包进行分组 、 组装,以及不能对数据包进行排 序,这些都是它和 TCP 最主要的区别 。

使用 UDP 发送报文后,是无法得知其是否安全,以 及是否完整地到达目的地的 。

UDP 将网络数据流量压缩成数据包的形式,一个典型的数据包就是一个二进制的数据传输 单位,

每一个数据包的前 8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。

因为 UDP报文没有可靠性保证、 没有顺序保证,以及没有流量控制等功能,所以它可靠性较差 。 但是,正因为 UDP 的控制选项较少,在数据传输过程中延迟小 、数据传输效率 高,因而适合对可靠性要求不高的应用程序 。

UDP 和 TCP 都属于传输层协议 。

扫描二维码关注公众号,回复: 5820679 查看本文章

在选择使用某种协议的时候,选择 UDP 必须要谨慎,因为在网络质量不好的情况下,

UDP 的数据包丢失的情况会比较严重,但正是因为它是无连接型协议,因而具有资源消耗 小、处理速度快的优点。 通常音频、 视频和普通数据在传送时使用UDP较多,因为它们即 使偶尔丢失一两个数据包,也不会对接收结果产生太大影响,如视频聊天时,丢失某些帧对 聊天效果 影 响不大 。

TCP 中包含了专门的传递保证机制,来确保发送的 数据 能到达对端, 并且是有序 的 。 UDP与 TCP不同, UDP并不提供数据传送的保证机制,如果在从发送方到接收方的传递过 程中出现数据报的丢失,协议本身并不能做出任何检测或提示,因此,经常把 UDP 称为不 可靠的传输协议 。

另外,相对于 TCP, UDP 的另外 一个不 同之处是不能确保数据的 发送 和接收的顺序

TCP 中提供了各种安全保障功能,但在实际执行的过程中会占用大量 的系统资源和开销, 这无疑使运行的效率,也就是运行速度受到严重的影响。 反观 UDP,由于排除了信息可靠 传递机制,将安全和排序等功能移交给上层应用来完成,因此极大地减少了执行时间,使运 行速度得到了保证 。

在使用 UDP 实现 Socket通信时,服务端与客户端都是使用 DatagramSocket类,传输的数据要存放在 DatagramPacket类中 。

DatagramSocket类表示用来发送和接收数据报包的套接字。

数据报套接字是包投递服务的发送或接收点 。

每个在数据报套接字上发送或接收的包都是单独编址和路由的 。

从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达 。

DatagramSocket s =new DatagramSocket(8888);

DatagramPacket类表示数据报包 。

数据报包用来实现无连接包投递服务 。每条报文仅 根据该包中包含的信息从一台机器路由到另一台机器。

从一台机器发送到另一台机器的多个 包可能选择不同的路由,也可能按不同的顺序到达 。

DatagramSocket类中的 public synchronized void receive(DatagramPacket p)方法的作用 是从此套接字接收数据报包。

数据报包对象的 length字段包含所接收信息的长度。 如果发送的信息比接收端 包关联的 byte[]长度长,该信息将被截短。 如果发送信息的长度大于 65507,则发送端出现 异常。

DatagramSocket类中的 public void send(DatagramPacket p)方法的作用是从此套接字发 送数据报包。

DatagramPacket包含的信息有:将要发送的数据及其长度 、 远程主机的 IP地 址和远程主机的端口号 。

DatagramPacket类中的 public synchronized byte[] getData()方法的作用是返回数据缓冲 区。

接收到的或将要发送的数据从缓冲区中的偏移量 offset处开始,持续 length长度。

测试发送超大数据量的包导致数据截断的情况

理论上,一个UDP包最大的长度为2^16-1(65536一1=65535),因此, IP包最大的发 送长度为 65535。 但是,在这 65535 之内包含 IP 协议头的 20 个字节,还有 UDP 协议头的 8个字节,即 65535一20- 8= 65507,因此, UDP传输用户数据最大的长度为 65507。 如果 传输的数据大于 65507,则在发送端出现异常 。

Datagram Packet 类中常用 API 的使用

DatagramPacket类中的 public synchronized void setData(byte[] but) 方法的作用是为此包 设置数据缓冲区。

将此 DatagramPacket的偏移量设置为 0,长度设置为 buf的长度。

DatagramPacket类中的 public synchronized void setData(byte[] b时, int o的时, int length) 方法的作用是为此包设置数据缓冲 区。

此方法设置包的数据 、 长度和偏移量。

DatagramPacket类中的 public synchronized int getOffset()方法的作用是返回将要发送或 接收到的数据的偏移量。

DatagramPacket类中的 public synchronized void setLength(int length)方法的作用是为此 包设置长度。

包的长度是指包数据缓冲区中将要发送的字节数,或用来接收数据的包数据缓 冲区的字节数。

长度必须小于或等于偏移量与包缓冲区氏度之和 。

使用 UDP 实现单播

使用 UDP 实现广播

“广播”就是将数据报文让其他计算机都知道 。

使用 UDP 实现组播

“组播”就是将数据报文让指定的计算机知道 。 组播也称为 多播 。

注意,如果在两台物理计算机中进行 UDP 组播的测试 ,一定要将多余的网卡禁用,不 然会出现使用 wireshark工具可以抓到组播包,但 receive()方法依然是阻塞的情况,但如果 服务端与客户端在同 一 台中,就不会出现这样的情况 。

如果是发送数据报包 , 则可以不调用 joinGroup()方法加入多播组 ;如果是接收数据报 则必须调用 joinGroup()方法加入多播组。

猜你喜欢

转载自blog.csdn.net/zhanglong_4444/article/details/89023361