【JavaEE初阶】-- 网络原理(传输层)

二、 传输层

传输层的核心作用是提供 "端到端" 的逻辑通信信道。

1. UDP协议

1.1 UDP 协议端格式

2. TCP协议

2.1 TCP协议端格式

4位首部长度: 首部指的是图上的前6行,前5行是固定的长度,20个字节,第6行是变长,TCP头部的长度表示的是固定长+变长。TCP头部最大长度是15*4byte=60byte.

6位标志位:

默认都是0,进行操作时,将对应的标志位置为1。

  1. URG:紧急指针是否有效,表示此段中包含紧急数据,应被优先处理。

  2. ACK:确认号是否有效,应答标志

  3. PSH:推送功能。提示接收端应该尽快将数据交付给应用层,而不是在缓冲区中等待更多数据。

  4. RST:对方要求重新建立连接。我们把携带RST标志的称为复位报文段。

  5. SYN:请求建立连接,我们把携带SYN标识的称为同步报文段,可以简单理解为发送标志

  6. FIN:通知对方,本端要关闭了,要求释放连接。我们称携带FIN标识的为结束报文段, 断开标志

2.2 确认应答

假设现在A、B在发信息,A每发送一个信息,都会得到来自B的一个应答。但是如果A同时发送多条信息,B会应答相应的条数,就会出现应答是错位的,分不清每个应答针对的是哪一条信息。

注意:应答和响应是不一样的。

  1. 应答只是一个标记,并没有真实的结果,仅仅是为了告诉发送方我收到了。

  2. 响应是针对请求计算出来的响应。

针对这种情况,TCP将每个字节的数据都进行了标号,即为序列号

每一个ACK都带着对应的确认序列号,表示自己已经收到了哪些数据,下一次你从哪里开始发送。

对应到上面的32位序号和32位确认序号:

每一端都既是发送方也是接收方。

自己的发送序列号:由发送方维护,用于标记它发出的数据。

自己的接收确认号:由接收方维护,用于确认它收到的数据。

2.3 超时重传(可靠性机制)

数据在网络上传输的过程中会经过很多网络设置,比如路由器、交换机、运营商、如果其中一个设置出现了问题,这个请求会超时。

1. 发送超时

主机B没有收到数据。A在达到超时时间后再发送一次。

2. 接收方收到了数据,返回应答时超时了

此时,主机A并不能确认究竟是发送丢包还是应答丢包。A不管究竟发生了什么,只要自己没有收到应答,在到达超时时间后就会再次发送数据。

那么对于主机B来说,他接收到了两次相同的数据,此时,主机B就能根据序列号来确认这个包是不是重复的包,如果是重复的,就会直接舍弃这个包,也就达到了去重的效果

超时重传的时间如何进行确认呢?

理想情况下这个时间越小越好,能够保证确认应答一定能在这个事件内返回就行。

但是这个时间的长短,是会随着网络环境的不同而变化的。

如果超时时间设置的太长,会影响整体的重传效率;如果设置的太短,可能会频繁发送重复的包。

TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间。

超时以500ms为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。如果重发一次之后,仍然得不到应答,等待2* 500ms再次进行重传;如果仍然得不到应答,等待4*500ms进行重传,以此类推,以指数形式递增。累计到一定的重传次数,TCP认为发生异常,强制关闭连接。

2.4 连接管理(可靠性机制)

作用:在发送方和接收方初次建立连接的时候,确认双方的收发能力。

2.4.1 初次建立连接时,三次握手

主要是验证网络状态,保证连接没有问题。

  1. 第一次握手

    主机A向主机B发送一个TCP数据包,同时会把这个TCP数据包中的SYN置为1,表示这是一个连接请求报文,并随机生成一个序列号填充在32位序号区域。

  2. 第二次握手(ACK + SYN)

    主机B在收到主机A发送的TCP数据报之后,会给发送方返回一个应答包,同时会把标志位ACK置为1,表示这是一个应答包。并将主机A发送的序列号 + 1 填充在确认序号区域。

    与此同时主机B也会生成一个随机数据填充在序号区域,并把标志位SYN置为1,表示这是一个连接请求报文。


  1. 第三次握手

    主机A接收到主机B发来的ACK + SYN请求时,首先判断ACK,表示主机B有应答能力,再去判断SYN,在序号的基础上+ 1,把结果填充在确认序号中,把标志位ACK置为1.

  2. 主机B接收到主机A发送来的ACK,表示主机A有应答能力,网络验证完成,建立连接成功。

1. 问:三次握手能不能变成两次或者四次?

答:四次可以,但是两次不行。两次就会少验证一方的应答能力。
2. 问:为什么第二次握手的ACK和SYN可以合并?

答:在三次握手阶段,双方的连接还未建立,双方都还没有开始传输任何应用层数据,没有任何负担。

2.4.2 断开连接时,四次挥手

  1. 第一次挥手
    主机A主动发起断开连接请求,给主机B发送一个TCP报文。该报文中会将主机B之前已经传送数据的最后一个字节的序列号加1填充到序列号中,并把标志位FIN置为1。
  2. 第二次挥手
    主机B接收到主机A发送的FIN包之后,会将主机A发送的序列号 + 1 填充到确认序号中,并将标志位ACK置为1。
  1. 第三次挥手

当主机B也将剩余数据发送完毕之后,它会发送一个FIN包。该包的中会将标志位FIN置为1,并把主机A之前已传送数据的最后一个字节的序列号+ 1填充到该包的序号中。

  1. 第四次挥手
    主机A收到主机B的FIN包后,发出确认包。该包会把标志位ACK置为1,并将主机B上一次发送到FIN包中的序号+ 1填充到确认序号中。

1. 四次挥手能合并成三次挥手吗?/第二次挥手和第三次挥手能合并吗?

答:大概率不能。

第二次挥手的ACK时操作系统级别做出的应答,是TCP协议本身的设计,和应用层无关。

第三次挥手的FIN是应用层去实现的,在发出FIN包之前需要回收一些资源之后才能触发。

2.5 滑动窗口(效率机制)

正常情况是发送一条数据等一个应答,应答中包含下次要发送的位置。

为了提升效率改为批量发送。窗口的大小指的是无需等待确认应答而可以继续发动数据的最大值。

发送方批量发送(根据当前窗口的大小发送报文),把正在发送的数据加入到缓冲区中,并记录最大字节数;接收方收到报文之后,返回一个ACK;发送方收到一个ACK之后,把缓冲区的数据删除椅子,然后再加入一组新的数据到缓冲区,继续发送。

窗口越大网络吞吐量就越大,效率越高,如果窗口无限大,就和UDP一样了。

2.5.1 异常情况

1. 数据报已抵达,ACK包丢了

图中的1001、3001、4001ACK是正常到达了主机A,但是主机A是正常接收到了6001的ACK,那么就代表6001前面所有的数据都传送成功了。

2. 数据包丢了,没有到达主机B

图中的是1001-2000的数据包丢失了,但是其他的数据包主机B都正常接收到了。

当某一段报文丢失了之后,接收端就会一直给发送端发送1001这样的ACK,发送端连续三次接收到同样的1001这样的ACK之后,就会将对应的1001-2000的数据重新发送。

此时,接收端重新正常接收到了1001的数据,就会给发送端发送7001的ACK。

这是因为之前正常接收的数据并不会被接收端舍弃,而是存放到接收端操作系统内核的接收缓冲区中。

2.6 流量控制(效率机制)

有了滑动窗口之后,提高了发送方是发送效率,并不是说发送方可以无限大为所欲为的发送数据了。

流量控制的作用就是用来通过接收方返回来的ACK进行反向控制送方的窗口大小。接收方会把自己能够处理的数据量主动告诉发送方,从而让发送方动态调整窗口的大小。

发送方在发送数据的时候,接收方会在自己的缓冲区中把接收到的数据按照编号组织好,等待着应用程序来读取。

如果接收端的缓冲区满了,就会将窗口置为0,这时发送方不再发送数据,但是会定期发送一个窗口探测,使接收端把窗口大小告诉发送端。

2.7 拥塞控制(可靠机制)

作用:通过网络的畅通程度来控制窗口的大小。

发送数据时,由于会经过很多网络设置,网络情况也是不固定的。在数据传输的过程中会造成阻塞和超时。

  1. 程序启动的时候会把拥塞窗口的值调到很低,比如1.

  2. 如果接收到接收端的ACK,表示当前窗口没有问题,就调大窗口。

  3. 窗口到达一定的阈值之前会以指数的形式增大,到达阈值之后,以1为步长进行增大。

  4. 当增大到一定程度之后就会出现丢包的情况,就证明网络阻塞了,这时就把窗口重新调成1,同时重置新的阈值为当前窗口的二分之一。

拥塞窗口的大小和接收端ACK应答中的窗口大小共同决定滑动窗口的大小,二者取较小值。

2.8 延迟应答

TCP在应答时,并不是每次都应答,而是每隔几次就进行应答,可能是2次。

假设我们现在是2次应答一次,那么如果只要3条报文就结束了,那么还可以通过时间间隔来进行应答,一般是200ms。

延迟应答和及时应答是不同的,在应答时都需要带上窗口大小。及时应答的窗口大小是缓冲区的剩余空间。

延时应答时,应用程序会从缓冲区中取走一部分数据,这时缓冲区的剩余空间就变大到了,ACK时窗口大小就可以设置更大的值,最终发送方就会按照这个值去增大窗口。

2.9 捎带应答

当主机A发送响应数据时,如果有ACK需要返回,那么这两个报文就有可能被合并成一个。这样减少了通信次数,提升了效率。

ACK是系统内核做出的应答(传输层)
发送响应是应用程序层面的(应用层)

2.10 面向字节流

创建一个TCP的socket,同时在内核中创建一个发送缓冲区和一个接收缓冲区。

调用write时,数据会先写入发送缓冲区。如果发送的字节数太长,会被拆分成多个TCP的数据包发出;如果发送的字节数太短,会先在缓冲区里等待,等到缓冲区长度差不多了,或者其他合适的时机发送出去。

接收数据的时候,数据也是从网卡驱动程序到达内核的接收缓冲区,然后应用程序可以调用read从接收缓冲区拿数据。

2.11 粘包问题

粘包指的是应用层的数据包

每接收到一个报文就把它放到缓冲区中,在读取报文时,不能有效的区分每个数据包的问题,称为粘包问题。

2.11.1 解决粘包问题一:定义一个分隔符

定义一个分隔符来界定消息之间的边界如果是换行符:\r\n

你好啊,一会儿去吃火锅\r\n行不行呀\r\n是不是在忙\r\nadflsjflsfj;lk;ds\r\n

2.11.2 解决粘包问题一:在应用层协议中定义一个区域,来表示当前消息的长度

2.12 异常情况

2.12.1 程序崩溃

系统会回收进程的资源,包括文件描述符表,回收时相当于调用socket的close(),触发FIN操作。

2.12.2 正常关机

处理方式和程序崩溃一样,都是正常断开连接。

2.12.3 主机掉电或断网

2.12.3.1 接收方断网

发送端接收不到接收端的ACK应答,会触发超时重传,多次重传之后发送端依旧没有收到ACK应答,会进行重置连接。如果连接重置也失败,只能放弃连接。

2.12.3.2 发送方断网

TCP自己也会定时发送心跳包,服务器定期扫描管理的连接,如果发现一个连接长时间没有发来心跳,就会主动丢弃这个连接。

3. 面试题:TCP和UDP协议的区别?

TCP:有连接、可靠传输、面向字节流、有接收缓冲区和发送缓冲区、大小不限、全双工。

UDP:无连接、不可靠传输、面向数据报、有接收缓冲区,无发送缓冲区、大小受限、全双工。

并详细讲述每一项。

相关推荐
Evan芙1 小时前
ifconfig 命令详解
linux·网络·ubuntu
云边云科技5341 小时前
企业SD-WAN选型指南:打造安全、体验至上的云网智联架构
网络·安全·架构·it·量子计算
njxiejing1 小时前
TCP连接详解:三次握手与实战分析(SYN,ACK,seq)
服务器·网络·tcp/ip
milanyangbo1 小时前
从硬盘I/O到网络传输:Kafka与RocketMQ读写模型及零拷贝技术深度对比
java·网络·分布式·架构·kafka·rocketmq
秋邱1 小时前
AR 定位技术深度解析:从 GPS 到视觉 SLAM 的轻量化实现
开发语言·前端·网络·人工智能·python·html·ar
2201_757830871 小时前
UDP协议
网络·网络协议·udp
梁辰兴1 小时前
计算机网络基础:引导型传输媒体
网络·计算机网络·计算机·计算机网络基础·引导型传输媒体
云飞云共享云桌面1 小时前
佛山某机械加工设备工厂10个SolidWorks共享一台服务器的软硬件
大数据·运维·服务器·前端·网络·人工智能·性能优化
卡次卡次11 小时前
注意点:多线程与多进程与在并行读-->并行cpu或者GPU处理--->并行写 的架构中,如何选择
linux·网络·python