【JavaEE】_传输层协议UDP与TCP

目录

[1. 开发中常见的数据组织格式](#1. 开发中常见的数据组织格式)

[1.1 XML](#1.1 XML)

[1.2 JSON](#1.2 JSON)

[1.3 Protobuf](#1.3 Protobuf)

[2. 端口号](#2. 端口号)

[3. UDP协议](#3. UDP协议)

[4. TCP协议](#4. TCP协议)

[4.1 特点](#4.1 特点)

[4.2 TCP报文格式](#4.2 TCP报文格式)

[4.3 TCP可靠性机制](#4.3 TCP可靠性机制)

[4.3.1 确认应答机制](#4.3.1 确认应答机制)

[4.3.2 超时重传机制](#4.3.2 超时重传机制)

[4.3.2.1 丢包的两种情况](#4.3.2.1 丢包的两种情况)

[4.3.2.2 重传时间](#4.3.2.2 重传时间)

[4.3.3 连接管理机制](#4.3.3 连接管理机制)

[4.3.3.1 三次握手建立连接](#4.3.3.1 三次握手建立连接)

[4.3.3.2 四次挥手释放连接](#4.3.3.2 四次挥手释放连接)

[4.3.3.3 建立连接与释放连接的总过程](#4.3.3.3 建立连接与释放连接的总过程)

[4.4 TCP效率提高机制](#4.4 TCP效率提高机制)

[4.4.1 滑动窗口协议](#4.4.1 滑动窗口协议)

[4.4.1.1 数据传输示意图](#4.4.1.1 数据传输示意图)

[4.4.1.2 滑动窗口](#4.4.1.2 滑动窗口)

[4.4.1.3 超时重传机制](#4.4.1.3 超时重传机制)

[4.4.1.3.1 第一种情况:ACK丢失](#4.4.1.3.1 第一种情况:ACK丢失)

[4.4.1.3.2 第二种情况:数据包丢失](#4.4.1.3.2 第二种情况:数据包丢失)

[4.4.2 流量控制](#4.4.2 流量控制)

[4.4.3 拥塞控制](#4.4.3 拥塞控制)

[4.4.4 延时应答](#4.4.4 延时应答)

[4.4.5 捎带应答](#4.4.5 捎带应答)


1. 开发中常见的数据组织格式

1.1 XML

  1. XML属于较早时期组织数据的格式,通过标签来组织数据

  2. 可以认为HTML是XML的变种,HTML的标签是规定好的,不允许程序员自创;

XML的标签都是程序员自定义的

以某请求为例:

XML 复制代码
<request>
    <userId> 1000 </userId>
    <position> 100,30 </position>
</request>
  1. XML的优势:可读性强;

XML的劣势:标签编写非常繁琐,传输时也会占用更多网络带宽;

  1. 目前阶段,在maven项目中会使用XML管理项目配置。

1.2 JSON

  1. JSON是当前最流行的一种数据组织格式。

  2. JSON是一种键值对结构,用一个{ }包裹所有键值对,如:

XML 复制代码
{
    userId:"1000",
    position:"100, 30"
}

其中,键值对之间用逗号分割,键与值之间用冒号分割,键为String类型键的双引号可以省略),值可以为数字、字符串、JSON、数组等等;

  1. JSON的优势:可读性强,比XML更简洁;

JSON的劣势:在网络传输中会消耗额外的带宽(key也需传输);

1.3 Protobuf

  1. 相比与json与xml,Protobuf(pb)是使用二进制的方式来组织数据的

  2. pb相当于把要传递的信息按照二进制形式压缩了,故而可以保证带宽占用最低;

  3. pb的优势:占用带宽最低,传输效率最高,非常适合对于性能要求较高的场景;

pb的劣势:可读性较差,一定程度上影响开发的效率;

2. 端口号

在编写一个服务器时,必须手动指定一个端口号,以区分当前主机上的不同应用程序;

在编写一个客户端时,系统会在客户端通信时自动分配一个端口号;

端口号长度固定为2字节,能表示的数据范围为0~65535,一般来说0是不使用的,其中:

(1)1~1023:熟知端口号,给一些知名服务器预留的端口号

如:22:SSH服务器(远程登录主机); 80:HTTP服务器; 443:HTTPS服务器

(2)1024~49151:登记端口号,要使用这类端口号必须在IANA按照规定的手续登记;

(3)49152~65535:短暂端口号,客户进程运行时进行动态选择,客户进程时临时使用;

3. UDP协议

  1. 特点:无连接,不可靠,面向数据报,全双工;

  2. 报文格式:

(1)UDP报文长度字段为16位,能表示的数据范围为0~65535,即64Kb,故而使用UDP时很难表示一个很大的数据报;,当传输较大数据时会发生截断;

(2)常用的校验方法有:CRC冗余校验、MD5、SHA1算法等;

  1. 基于UDP的应用层协议有:

(1)NFS:网络文件系统;

(2)TFTP:简单文件传输协议;

(3)DHCP:动态主机配置协议;

(4)BOOTP:启动协议(用于无盘设备启动);

(5)DNS:域名解析协议

4. TCP协议

4.1 特点

  1. 有连接,

  2. 面向字节流,

  3. 全双工:

体现在代码中:

  1. 可靠传输:(TCP最核心的特性)

TCP保证可靠传输是以确认应答为核心,借助其他机制辅助,最终完成可靠传输

TCP实现可靠传输的核心机制有:

(1)确认应答:

发送方发送数据后,接收方收到数据则返回一个应答报文(acknowledge,ack);

发送方收到应答报文就知道数据是否发送成功。

(2)超时重传:

在TCP传输过程中,丢包可能出现传输数据丢失返回的ack丢失两种情况,

但在发送方端是无法辨别的,但无论是出现了哪种情况,发送方都会进行重新传输。

重传操作大幅度提升了数据传输成功的概率,是重要的丢包补救措施。

(3)连接管理:

连接管理即建立连接(三次握手)和释放连接(四次挥手);

4.2 TCP报文格式

(1)TCP数据报=首部(报头)+数据载荷。其中报头长度不固定:

当选项部分不存在时,报头最短,为20字节

当选项选中且长度最长(40字节)时,报头最长,为60字节

(2)首部(4位),表示的范围为0~15,单位为4字节

即当首部为0xF(15)时,表示首部长度为15×4字节=60字节,达到首部最大长度;

4.3 TCP可靠性机制

4.3.1 确认应答机制

注:(1)在TCP报文首部中,有一个ACK字段值为1时,该数据报中的"确认序号字段"有效

当ACK字段为0时,表示当前数据报中的"确认序号字段"无效;

(2)TCP是按照字节进行编号(序列号)的:

4.3.2 超时重传机制

4.3.2.1 丢包的两种情况

对于第二种ACK丢失的情况,站在主机B的角度收到了2条数据,会不会导致bug是需要思考的问题。

TCP设置了一个接收缓冲区,在该内存空间中保存已经收到的数据及数据的序号

如果接收方发现当前发送方发来的数据已经在缓冲区中存在,则判定为重复发送,直接将其丢弃。确保应用程序read时只能读到一条数据。

且接受缓冲区除去重外,还可进行重新排队。保证发送的顺序和应用程序读取的顺序是一致的。

4.3.2.2 重传时间

发送方发送数据后会进行等待,如果在等待时间内收到对方的ACK,则视为数据成功送达;

如果超过了等待时间,还没有收到ACK,就会触发重传机制

(1)超时时间的设定并不简单,如果超时时间设的太长,会影响整体的重传效率;如果超时时间设的太短,有可能会频繁发送重复的包;

(2)初始等待时间是可以进行配置的,不同系统上的等待时间也不一定相同,可以通过修改内核参数来进行修改;

(3)等待的时间也会动态变化,超时次数越多,下一次等待时间会变长。但也不是无限变长,重传若干次则视为不可达,触发TCP的重置连接,即放弃此条连接。

(4)在Linux和Windows中,超时以500ms为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。比如,重发一次后仍然没有得到应答,就会等待2*500ms后再进行重传。累积到一定次数后,TCP认为网络或对端主机出现异常,强制关闭连接。

4.3.3 连接管理机制

4.3.3.1 三次握手建立连接
  1. A还要发送第三次确认的意义在于:

可以防止已失效的连接请求报文段突然又传送到了B,因而产生错误

  1. 三次握手的核心作用:

(1)确认当前网络是否通畅;

(2)发送方和接收方确认自己发送能力与接受能力正常;

(3)让通信双方在握手过程中针对一些重要参数进行协商,如通信数据的开始序号;

4.3.3.2 四次挥手释放连接
  1. 四次挥手中间的两次交互不一定能合二为一,这与三次握手建立连接不同。

(1)对于三次握手:

ACK与第二个SYN都是内核触发的,同一个时机可以合并;

(2)对于四次挥手:

ACK与第二个FIN的触发时机是不同的:

ACK是内核触发的,B收到FIN就会立刻返回ACK;

第二个FIN是应用程序的代码触发,B方调用close方法才会触发FIN

从服务器收到FIN并发送ACK后,再到执行close发起FIN中间要经历多少时间是不确定的。

4.3.3.3 建立连接与释放连接的总过程

注:TIME_WAIT状态需要等待2MSL(最长报文段寿命)存在的意义:

(1)假如没有设置TIME_WAIT状态而令A直接进入关闭状态,如果最后一个ACK丢失了,B会超时重传FIN,而A已经释放连接,则重传的FIN就无法被A收到。

而设置了TIME_WAIT状态后,如果对方重传了FIN,A就可以继续返回ACK了。

即:保证最后一个ACK能够到达对方

(2)防止已失效的连接请求报文段出现在本连接中,A发送完最后一个ACK后再经过2MSL,就可以使本连接持续时间内所产生的所有报文段都从网络中消失。

4.4 TCP效率提高机制

4.4.1 滑动窗口协议

已知TCP的可靠传输会影响传输的效率,故而提出了滑动窗口协议用于尽可能降低可靠传输对性能的影响;

对于一发一收传输方式:

这种传输方式的等待时间是较长的;

批量传输方式:

4.4.1.1 数据传输示意图

无需等待ACK返回直接发送下一个数据。设置一个批量发送数据的最大限度,达到上限后再同意等待ACK。将这个数据量上限称为窗口大小。

4.4.1.2 滑动窗口

(1)当前A向B批量发送了4份数据,达到发送窗口大小,停止发送,等到B的ACK;

(2)B收到A的4份数据后,向A发送4个ACK;

(3)当A收到B对第一份数据的ACK后,就将窗口滑动,继续发送第五份数据;

4.4.1.3 超时重传机制
4.4.1.3.1 第一种情况:ACK丢失

此种情况无需重传。

确认序号表示当前序号之前的数据已经全部接收到了,下一个希望收到当前序号的数据包。

故而如果1001的ACK丢失了,而2001的ACK成功返回则表示2001号之前的数据都已经传输成功了,包括了1001ACK的含义。称为累积确认。

4.4.1.3.2 第二种情况:数据包丢失

(1)当主机B向A发送1001号ACK时,表示下一个希望收到1001及以后得数据包;

(2)主机A发送给主机B的1001~2000号数据包丢失,故而主机B未收到期待序号的数据包。主机B无论主机A继续发送什么序号的数据包都不予确认,而是连续发送三个重复确认ACK,向主机A索要1001号数据包;

(3)当主机A收到主机B发来的连续重复确认后,就开始重传1001~2000号数据包。

(4)当主机B成功接收1001~2000号数据包后,对这段时间主机A所发送的多条数据包进行累积确认,即发送7001号ACK;

注:

(1)上述重传操作中,并没有额外的冗余操作,哪个数据丢失就重传哪个,没有丢失的无需重传,整个过程比较迅速,称为**快速重传,**是滑动窗口协议下的对超时重传机制的变种。

(2)如果通信双方传输数据量较小,也不频繁,就仍然是普通的确认应答和普通的超时重传;

如果通信双方传输数据量较大,也较频繁,就会进入滑动窗口模式,进行快速重传的方式处理。

4.4.2 流量控制

流量控制即:根据接收方的接受速率,控制发送方的发送速率。

避免出现发送方发送太快导致接收方来不及接收的情况

(1)主机A向主机B发送数据后,数据先到达B的系统内核中。TCP socket对象上带有接收缓冲区,A发送给B的数据就会先到达B的接收缓冲区;

(2)B的应用程序会调用read这样的方法,把数据从接收缓冲区中读出来进行进一步的处理。

一旦数据被read了,就可以从缓冲区删除了;

注:(1)对应TCP报文格式,其中的"16位窗口大小"用于表示接收缓冲区剩余空间大小。但此处空间最大值并非64K,在TCP报头中的选项部分有一项叫做"窗口扩展因子",可以对窗口大小进行左移位,从而表示更大的范围;

(2)TCP规定,即使接收窗口为0,也必须接收窗口探测报文、确认报文段以及携带紧急数据的报文段;

4.4.3 拥塞控制

  1. 拥塞控制即:防止过多的数据注入到网络中,使网络中的路由器或链路不至于过载,是一个全局性的问题;

而流量控制往往是指点对点通信量的控制,是个端到端的问题。

注:(1)在TCP建立连接和网络出现超时时,采用慢开始和拥塞避免算法,当发送方接收到冗余ACK时,采用快重传和快恢复算法

(2)流量控制和拥塞控制都是在限制发送方窗口的大小,最终发送的窗口大小为流量控制与拥塞控制窗口中的较小值

4.4.4 延时应答

  1. 正常情况下,A把数据传输给B,B就会立即返回ACK给A;

但有的时候A传输给B,B等待一段时间后再向A返回ACK,此时就是延时应答;

  1. 比如在流量控制中,可以使用延时返回ACK,以给接收方更多的时间来读取接收缓冲区的数据,缓冲区的空间会更大,使得可以返回的窗口大小也增大了。

4.4.5 捎带应答

由于TCP延时应答的存在,有可能存在以下情况:

(1)ACK是内核立即返回的,response是应用程序代码返回的,二者时机是不同的;

(2)TCP引入延时应答后,B对A的ACK可能不是立即返回,在其延时返回的过程中,可能B就计算好response,此时就可以将业务数据response捎带ACK进行返回:

(3)将两个数据包合二为一个数据包进行发送,可以实现更高效地传输;

相关推荐
bpmf_fff2 分钟前
十、事件类型(鼠标事件、焦点.. 、键盘.. 、文本.. 、滚动..)、事件对象、事件流(事件捕获、事件冒泡、阻止冒泡和默认行为、事件委托)
前端·javascript
计算机学姐5 分钟前
基于SSM的宠物领养平台
java·vue.js·spring·maven·intellij-idea·mybatis·宠物
Dearrrrrrrr5 分钟前
H3C OSPF 多区域实验
网络·计算机网络·智能路由器
泰山小张只吃荷园15 分钟前
期末Python复习-输入输出
java·前端·spring boot·python·spring cloud·docker·容器
Mr_Xuhhh17 分钟前
程序地址空间
android·java·开发语言·数据库
fpcc18 分钟前
c++应用网络编程之十五Nagle算法
网络·c++
YSRM23 分钟前
异或-java-leetcode
java·算法·leetcode
大明湖的狗凯.26 分钟前
MySQL 中的乐观锁与悲观锁
java·数据库·mysql
z2023050832 分钟前
linux之调度管理(13)- wake affine 唤醒特性
java·开发语言
AI人H哥会Java33 分钟前
【JAVA】Java高级:Java网络编程——TCP/IP与UDP协议基础
java·开发语言