聊聊TCP

关于TCP/IP

TCP/IP协议族是互联网使用最广泛的基础通信协议,其中TCP(Transmission Control Protocol)为网络通信提供了可靠性保证。TCP协议本身非常复杂,深入研究的话还是需要去看《TCP/IP详解 卷1:协议》,本文仅仅是对TCP/IP作一个不完全的介绍。

OSI参考模型

先说OSI协议(Open System Interconnection),OSI是由ISO制定的一个国际标准,对通信系统进行了标准化。但是OSI协议并没有得到普及,反而是OSI协议的指导方针“OSI参考模型”常被用于网络协议的制定。OSI将计算机网络体系结构划分为以下7层:

7 应用层

各种应用程序协议 ,如HTTP、FTP、SMTP、POP3。

6 表示层

信息的语法语义以及它们的关联,如加密解密、转换翻译、压缩解压缩。

5 会话层

不同机器上的用户之间建立及管理会话。

4 传输层

接受上一层的数据,在必要的时候把数据进行分割,并将这些数据交给网络层,且保证这些数据段有效到达对端。

3 网络层

控制子网的运行,如逻辑编址、分组传输、路由选择。

2 数据链路层

物理寻址,同时将原始比特流转变为逻辑传输线路。

1 物理层

机械、电子、定时接口通信信道上的原始比特流传输。

TCP/IP参考模型

TCP/IP是由IETF定义的标准。TCP/IP将结构划分为4层,分别是应用层、传输层、网络层和网络接口层,与OSI参考模型十分相似,每一层的定义也基本相同。但为了方便分析和学习,我们通常会将网络接口层分为数据链路层和物理层,即划分为5层:

5 应用层

HTTP、FTP、SMTP、POP3等。

4 传输层

TCP(Transmission Control Protocol)、UDP(User Datagram Protocol)在这一层,这一层传输的数据称为数据段(Segment)。

3 网络层

IP(Internet Protocol)在这一层,这一层传输的数据称为数据包(Packet)。

2 数据链路层

ARP(Address Resolution Protocol)在这一层,这一层传输的数据称为数据帧(Frame)。

1 物理层

这一层传输的数据是比特(Bit)。

TCP三次握手和四次挥手

三次握手

[Client] ——- SYN ——> [Server]

[Client] <— ACK,SYN —- [Server]

[Client] ——- ACK ——> [Server]

SYN的全称是Synchronize Sequence Number,表示同步序列号。

ACK的全称是Acknowledgement Number,表示确认收到。

三次握手的目的是建立可靠的通信连接,从技术实现的角度来说,主要是要初始化Sequence Number的初始值。通信的双方要互相通知对方自己的初始化的Sequence Number(缩写为ISN:Inital Sequence Number)。这个号要作为以后的数据通信的序号,以保证应用层接收到的数据不会因为网络上的传输的问题而乱序(TCP会用这个序号来拼接数据)。

其中关于ISN的初始化,在每次建立TCP连接时,ISN是不能固定从0开始或者其他有可能重复的值,否则将无法严格区分不同时间不同连接的数据包导致乱套。

四次挥手:

[Client] ——- FIN ——> [Server]

[Client] <—– ACK ——- [Server]

[Client] <—– FIN ——- [Server]

[Client] ——- ACK ——> [Server]

四次挥手的目的是断开一个TCP连接,由于TCP是双向通讯协议,要结束连接,双方都必须发送终止信号,告诉对方后续再没有数据发过来了,并等待对方确认。

TCP协议如何保证可靠传输

TCP在保证可靠传输上做了大量的工作,用了很多复杂的算法,一篇文章其实是讲不完的,更何况我也只是一知半解。简单来说,主要有3个机制:

  1. 重传机制

    TCP是分组交换,也就是把一个大数据分割成一个个较小单位的数据包进行传输,以此提高通信的效率和利用率。那么就有2个问题:

    • 在发送数据的过程中,部分数据有可能会丢,那么丢多少,需要重传多少是个问题。
    • 什么时候重传是个问题,TCP使用超时重传机制,但是对超时时间的设置很重要,长了,太慢,没有效率。短了,会有很多不必要的重发,还会增加网络拥塞,导致更多的超时,更多的超时导致更多的重发。

    经过多年的优化,TCP最终使用一个叫Jacobson/Karels Algorithm的算法,能够较为准确的估算出重传的超时时间,让重传机制更高效。

  2. 滑动窗口

    TCP滑动窗口主要用于解决流控问题。TCP连接的两端都有一个固定大小的缓冲区,TCP头里有一个字段叫Window,又叫Advertised-Window,这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。

  3. 拥塞处理

    简单来说,滑动窗口仅仅是解决了发送端和接收端的拥塞问题,但对于网络上的拥塞无能为力,但是TCP也希望能够解决这个问题。

    拥塞控制主要是四个算法:

    • 慢启动

      刚刚加入网络的连接,一点一点地提速。主要是通过调整拥塞窗口cwnd(全称Congestion Window)来提速。

    • 拥塞避免

      有一个ssthresh(slow start threshold),是一个上限,一般来说ssthresh的值是65535,单位是字节,当cwnd >= ssthresh时,就会进入“拥塞避免算法”,避免增长过快导致网络拥塞,通过一个线性上升的算法慢慢增加cwnd,调整到网络的最佳值。

    • 拥塞发生

      在拥塞的时候,TCP一般会有两种处理方法:

      一种是快速重传算法,会在收到3个重复ACK时开启,而不用等到超时才开始重传。

      另一种是等到超时,这种情况是比较糟糕的,所以TCP反应比较强烈,先将sshthresh设置为cwnd的一半,并重置cwnd为1,然后进入慢启动过程。

    • 快速恢复

      快速重传和快速恢复算法一般同时使用。快速恢复算法认为,可以收到3个重复ACK说明网络还不是那么糟糕,于是先重传丢失掉的数据包,如果还算正常就快速调整cwnd恢复网络传输速度,然后进入到拥塞避免算法。

TCP和UDP的区别

TCP:

面向连接,传输可靠,传输字节流,传输效率慢,占用资源多,适合要求通信数据可靠的场景。

UDP:

面向无连接,传输不可靠,传输数据报文段,传输效率快,占用资源少,适合要求通信速度高的场景。

参考文档

《图解TCP/IP》

https://coolshell.cn/articles/11564.html

https://coolshell.cn/articles/11609.html

Table of Contents