[网络原理] TCP 协议的相关特性

TCP和UDP都是传输层的协议.


1. TCP协议格式

TCP的特点是有连接,可靠性,面向字节流,全双工.
在这里插入图片描述

  1. 源端口和目的端口
    TCP的源端口与目的端口一样,表示端口号.
  2. 32位序号和32位确认序号我们放在后面的知识里学习
  3. 首部长度,代表一个TCP报头.TCP的首部长度不固定,图中的首部长度为4字节,也就是16个比特位,如果首部长度为6,那么整个TCP报头就为48个比特位.
  4. 保留位,提高TCP的可扩展性.以防TCP想引入新的功能,操作的成本很高,这时就可以使用这些保留位字段,在不影响原有结构的基础上进行升级.
  5. 校验和与UDP原理相同.
  6. 窗口大小和紧急指针我们放在后面详细解释.
  7. 选项,这个部分是对TCP报文的一些属性进行说明.

2. TCP连接及断开连接管理

正常情况下,TCP连接要进行三次握手,断开连接要进行四次挥手.
TCP连接及断开连接问题,是面试中常考的问题,我们需要画图解释.

2.1 三次握手

如下图,是客户端与服务器建立连接的流程图.
在这里插入图片描述
图中我们要注意两个状态
A. 服务器的第二个状态,LISTEN,代表服务器服务器已经做好连接的准备,可随时与客户端建立连接.
B. 客户端与服务器的最后一个状态都是ESTABLISHED,代表此次连接建立成功,可以正常通信.
如果面试题中,要求描述三次握手的过程,我们只需画出下图.
三次握手的本质是,各自要向对方发起一次建立连接的请求,并在接收到对方的请求时立即返回一个ACK.
在这里插入图片描述

  1. 首先,必须由客户端主动发起建立连接的请求,发送的syn为同步报文段
  2. 服务器在收到建立连接请求后,会立即返回一个ack.
  3. 之后,由服务器发起建立连接的请求.
  4. 最后,客户端在接收请求后立即返回一个ack.

有同学会有疑问了,为什么一共有四次交互,却是三次握手呢?
由于第2,3步之间时间间隔很短,可以合并.所以协议将这两步封装到一起.所以成了三次握手.也可以节省开销.

那两次握手可不可以呢?答案是不行.为啥呢?
其实,三次握手还有一个意义,就是验证客户端和服务器的收发功能都没问题.
如下图,当客户端发送请求时,只有服务器返回ack了,才确定客户端的发送能力没问题,服务器也保证自己的接收能力没问题.
而只有当客户端在接收请求后返回ack时,才保证了服务器的发送能力没问题,客户端的接受能力没问题.
之后才可以进行数据的发送.
在这里插入图片描述

2.2 四次挥手

如下图,是断开连接四次挥手的具体流程.
在这里插入图片描述
这里有两个重要的状态

  1. 服务器端的CLOSED_WAIT,此时正等待close方法关闭socket.
  2. TIME_WAIT,客户端进入到TIME_WAIT状态时代表四次挥手已经完事了.但是有一点要注意,在服务器端还没收到ACK之前,TCP连接还不能断.由于最后这个ACK有丢包的可能,一旦这个ACK没发过去,服务器也就无法得知自己的FIN是否成功发送,在一段时间之后,服务器会再次尝试发送一次FIN,一旦连接断开了,就发不了了.
    所以,客户端进入到TIME_WAIT状态后,会等待2MSL(MSL为两个节点之间数据传输消耗的最长时间,可人工规定),过了这个时间,确认未丢包后,则彻底释放连接.

面试中如问到这个问题,画出下图即可.
在这里插入图片描述

  1. 客户端的应用程序主动调用socket的close方法或者进程退出,会触发FIN.注意,断开连接可能由客户端发起,也可能由服务器发起.
  2. 客户端接收到断开请求,自动返回一个ACK.
  3. 服务器的应用程序执行到对应的close方法,会触发FIN.
  4. 客户端接收断开请求,自动返回ACK

那么这里第2,3步为什么不能合并呢?由于服务器端在接收到断开请求后,还能做一些事情(根据代码而定),所以第2,3步之间有一定的时间差,不能进行封装.

3. TCP可靠性机制

3.1 确认应答

确认应答是实现TCP可靠性的最核心机制.

  1. 应答报文,确认应答机制由应答报文(ACK)实现.A给B发个消息,当B收到消息后,会立即给A返回一个ACK,那么A收到ACK后就知道自己的消息发送成功了,来保证可靠性.
  2. 确认序号,另外,要保证消息的顺序不能乱.所以,我们需要给消息进行编号,为确认序号.序号按字节排序,第一个字节为序号1.
    如下图所示,第一组数据报为1-1000字节,确认序号为1,第二组数据报为1001-2000字节,确认序号为1001,当确认序号为1001时,就确认了1-1000组的数据报已经成功发送.当确认序号为2001时,就代表2000之内的数据已正确发送.
    在这里插入图片描述

3.2 超时重传

如果发送端迟迟没有收到接收端返回的ACK,就无法确认数据是否被正确传输.
TCP引入了重传机制,程序员可以根据具体情况,设置一个时间域值,在发送端发送数据之后,开始计时,一旦超过这个时间阈值,无论数据是否丢失,都视为数据丢失,发送端重新传送数据.
但这里会出现一个问题,一个消息传的很慢,超过时间阈值之后仍未传达.此时,发送端重新发送数据,那么这同一个消息可能会发送了两次.
如何解决这个问题呢?TCP的接收端有接收缓冲区,会以优先级队列的方式,将消息进行排序,将相同的消息进行去重.

4. 滑动窗口

由于每发送一条消息,就要返回一个ACK,之后才可以发送下一条消息,很消耗时间.因而,TCP设置了滑动窗口机制.
如下图,一次发送多条消息,之后,等待这一组数据的ACK.节省了很多时间
在这里插入图片描述
把不需要等待就能直接发送的数据的最大的量称为窗口大小.
需要注意的点是,在客户端等待一组数据的ACK时,并不需要等待所有ACK都到,再集中发下一组数据,而是到一部分就可以发下一部分.例如客户端收到1001的ACK,就代表1-1000之间的ACK已经全部被确认,就可以发送下一个1000数据报即(3001-4000)了.
若有1-1000出现丢包情况,则只需重传1-1000的数据报即可,之后在接收缓冲区进行重新排队.

5. 流量控制

滑动窗口有几个问题.

  1. 若一次性发太多消息,但接收端处理不过来,就白发了.发送端的发送速度不能超过接收方的处理能力.
  2. 窗口太大,也会消耗过多系统资源.
    所以,要根据接收缓冲区的大小确定下一次发送的窗口大小.
    每发送一组信息,就返回一次接收缓冲区大小,从而调整发送方的窗口大小.当窗口为0时,暂停发送.
    之后,发送方定期发送窗口探测报文,触发ACK查看窗口大小的机制.

6. 拥塞控制

流量控制和拥塞控制共同决定发送方窗口大小.
滑动窗口有个问题,就是一开始的时候,并不知道窗口大小,若此时贸然发送大量数据,可能加重网络拥塞.
因而TCP引入拥塞控制,引用慢启动机制,先发送少量数据,确认一下当前网络的拥堵状态,在确定之后的窗口大小.

如下图,为拥塞窗口变化图.
在这里插入图片描述

  1. 刚开始,窗口大小为1,试探网络拥塞程度
  2. 发现未丢包,以指数形式扩大窗口
  3. 引入慢启动阈值,达到阈值,这里阈值为16,则停止指数增长,开始进行线性增长.
  4. 网络拥塞达到极限,窗口重新回到慢开始阶段.
  5. 进行新一轮的重复.

7. 延迟应答

延时应答也是提升效率的机制.是在收到数据后,不要立即返回ACK,而是延时以下,处理一下接受缓冲区里的数据,以便下一次的发送窗口能更大一些.

8. 捎带应答

由于上面的延时应答机制,客户端发送数据,服务器并不会立即返回ACK,而是会延迟一下.而此时,若到了服务器发送下一条消息的时机,服务器可把上次的ACK捎带上,一同发送给发送方.

9. 面向字节流

TCP面向字节流,接收缓冲区会把收到的数据放在一起,从而难以区分读到那算是完整的一条数据.这种情况称为粘包问题.
解决办法

  1. 约定好分隔符
  2. 约定好每个包的长度

10. 异常情况

  1. 进程终止,释放文件描述符表,正常断开连接.
  2. 主机关机,先关进程,再关机,与上一种情况相同
  3. 主机断电/网线断开,若是接收方断电了,发送方一直等不来ACK,超时重传几次依旧等不到,就放弃连接了.若是发送方断电,接收方发现没数据了,会周期性向发送方发送一个消息(心跳包),确认对方是否工作正常.

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值