TCP是面向连接的。而且提供的是全双工服务,即如果两台主机A和B相连,那么A可以给B发数据,B也可以给A发数据。TCP连接是点对点的,即在单个发送方与单个接收方之间的连接。

建立连接的过程

客户首先发送一个特殊的TCP报文段,服务器用另一个特殊的TCP报文段来响应,最后,客户再用第三个特殊报文段作为响应。

前两个报文段不承载“有效载荷” ,也就是不包含应用层数据;而第三个报文段可以承载有效载荷。

数据传输

一旦建立了连接之后,就需要传输数据。当应用层数据通过套接字以后,数据就交由TCP控制。TCP将这些数据引导到该连接的发送缓存里,然后不时的从发送缓存里取出一块数据,并将数据传递到网络层。

image-20230425102632021

TCP报文段结构

image-20230425102923389

其中,32比特的序号字段和32比特的确认号字段被TCP发送方和接收方用来实现可靠数据传输服务。

接收窗口字段用来实现流量控制。

TCP被称为累计确认是因为它的确认号也是按组确认的。比如说收到了0-500的报文段,那么它发送给发送方的确认号就是501,如果收到0-500,和600-900,而没有收到501-599,那么确认号还是501。

TCP的发送方,也使用了流水线。

可靠数据传输

由于网络层提供的服务(IP服务)是不可靠的,无法保证数据按序交付,也无法保证完整性。而TCP则是建立在IP提供的网络服务之上,它创建了一种可靠数据传输服务。

快速重传

TCP有一种机制,就是延长超时时间,比如说第一个字数据经过50ms,被却认为丢失,然后重发,那么第二个就会将超时时间设置为100ms,以此类推。但是这会导致超时的时间越来越长,增加了端到端的时延。

解决办法是引入了快速重传,即通过冗余的ACK确认,来得知是数据错误,而不需要等待超时时间到达。

冗余的ACK就是再次确认已经收到的某个报文段的ACK,而发送方之前也已经收到该报文段的ACK。

一个具体的例子就是,比如说ACK = 3是一个数据的确认,而且发送方也已经接收到了ACK = 3的确认帧,而接收方收到了数据5和6,没有收到4,此时接收方就会重传ACK = 3的确认帧,如果重传超过3次,则TCP就启动快速重传,立即重传3之后的数据。

选择重传

回退N帧协议,假设分组n的确认报文丢失,那么它会重传n以及n以后的所有报文,尽管只丢失了n,其他的全部已经正确接收。

而TCP则是允许接收方有选择的确认失序报文段,而不是累计的确认正确的接收最后一个。当启用重传时,它就会跳过重传那些已经被接收方选择性确认过的报文段。

流量控制

TCP连接的每一侧都为该连接设置了接收缓存。没当TCP接收到正确,按序的字节后,就会将这些数据放入接收缓存,相关的应用就会从接收缓存中读取数据。但是如果应用读取的比较慢,而发送方发送的比较快,则会导致缓存溢出。

所以TCP提供了流量控制服务,以消除发送方发送过快导致接收方缓存溢出的可能。

TCP通过让发送方维护一个接收窗口的变量来实现流量控制。接收窗口用于给发送方指示,表明现在接收方还有多少可用的缓存空间。因为TCP是全双工通信的,所以说连接两端都会维护一个接收窗口。

这样一来,发送方只需要根据对应接收方的窗口大小来确定此时可以发送多少数据,就能保证不溢出。

参考

《计算机网络:自顶向下方法》