TCP协议的报文格式
TCP协议有连接,可靠性传输,面向字节流,全双工。
他的数据格式如图:
根据他的数据格式,在这里我们只知道 16位源端口号(表示客户端这里的端口号),16位目的端口号(服务器这边的端口号),还有16位校验和(这里在UDP中的校验和是一样的)。
这里的选项其实就是 "可选" 或 "不选",没有更加深层的含义。
在这里学习之前我们只能了解到这几个,在后面介绍10大机制的时候会一一介绍。
TCP的十个核心机制
(1) 确认应答。
确认应答这种机制其实是为了保障,TCP协议可靠传输的这种特性。
那么怎么确认应答的呢?
当客户端A,发送过来一个数据的时候。服务端B,这里不会立马给出响应,而是先发送一个,ack这样的报文,告知A,已确认收到。这里的ACK其实就是上面,保留位的其中之一。
那么在这里我们就需要考虑一个问题,当A一起发送两个数据的时候,那么,B这边是如何保证发送的ack报文,是怎么一一对应的呢?
因此在这里我们的TCP协议,包含确认序列号,当A每次发数据的时候都会进行编号,B返回的时候,就会根据这个序列号,来进行一一对应。
此处的序列号,也就是上述TCP报文格式中的32位序列号和32位确认序列号。
如图:
(2)超时重传。
这里我们先考虑一个问题。当我们客户端A,发送数据包是,经过中间的层层传输,还未传给服务端B的时候,突然丢包了怎么办?此时,A就不会收到B这边的应答报文。
这里我们就会触发,超时重传。意思就是:等了一会没有A,还没有收到,B这边的ack报文,此时,A就会再发一遍数据。
如图:
还有情况是当B这边返回的ack报文,丢包了怎么办?考虑,超时重传,此时A会再次重新发送一次数据,这种很明显时很不合理的。
如图:
就如上述图中所说的,当发生在转账的时候,A就会发起两次充值,而B只返回一次。此时就是一个非常糟糕的事情。
那么在这里我们怎么解决呢?
其实在操作系统中,存在一种数据结构, "接收缓冲区" 类似于阻塞队列这种结构。每当B收到A发到的数据之后,B的这种数据结构会根据序列号,对数据进行排序,序列小的在前序列大的在后。
如图:
当重传多次还未成功怎么办?
如果多次尝试了还未成功此时,就会重置连接,通过复写报文,"RST报文" 来重置连接,也是上述保留位的其中之一。
(3)连接管理。
建立连接的流程:三次握手。
断开连接的流程:四次挥手。
在握手和挥手的过程中,传输的网络数据包,不携带任何的业务上的数据。
三次握手
三次握手形象的表现,其实就是投石问路,传输的数据仅起到的作用,就是确保网络传输通畅,不携带,任何的业务逻辑数据。
建立连接,其实就是通信双方,各自保存对端的信息。
具体完成上述的过程,需要进行三次网路的交互。
如图:
其实上图中的,流程一共进行了三次的交互,只是中间的两次交互,ACK和SYN两个和成了一个数据包了。
这里的SYN也是6个标志位的其中之一,其实是synchronize 的缩写,这里是同步的意思。
那么这里问什么要各自发送syn呢?
当客户端A发送数据后,服务端B返回给A一个ack报文,此时B再给A一个syn确定A的接收能力是否正常。只有这样才能确保通信双方,网络通信正常。
三次握手的过程中还需要,协商一些重要的参数。
在这里序列号往往不是从一开始的,而是通信双方通过协商确定的。
三次握手主要意义三个方面:
1.投石问路,确定通信双方路径是畅通的。
2.验证双方的发送能力和接收能力。
3.协商必要的参数,比如起始序号等。
补充如图:
四次挥手
如图:
这里的四次挥手,不一定是客户端先发出的,也可能是服务端。三次握手,一定是客户端先发出的的。
那么啥叫断开连接?就是通信双方,都把各自的信息都给删了。
这里的FIN(结束报文)其实也是6个标志位之一,就是finally的缩写。
这里,四次挥手中,中间的两次通信是否可以合并?
常规情况下是不可以合并的,再特殊的情况下可以合并。
那么为什么不能合并呢?
三次握手过程中,syn和ack都是内核自动控制发送的(其实是同一时机),因此可以合并。
如图:
TCP状态如图:
(4)滑动窗口。
滑动窗口是提高传输速率的机制。
当我们不引入滑动窗口时 如图:
引入滑动窗口时,如图:
如图中所示,引入滑动窗口会大大提高传输效率。
当上述A,发送的1001-2000的序列号的数据,此时B发送这一序列号的报文丢失了怎么办呢?
其实这种情况完全不用担心,因为,此时ack丢包了,但是数据已经收到了,后面当B返回给A一个序列号位3001的ack,A就会默认小于3001 的数据B已经全部收到了。
那么,在这里A发送的数据报直接丢失了怎么办?例如:1000-2000 的数据丢失了。
如图:
当丢失了之后,此时B会一直返回1001序列号的应答报文,一直向A索要,等待A发送了之后,B就会返回,已经接收到的应答报文,如图中的7001序列号的报文。
如图B的结构:
(5)流量控制。
这里的流量控制,其实就是控制的窗口的大小,来控制发送方的速度。
具体是怎么控制的呢?
如图:
还有就是,上述的TCP报文格式中的 "选项" ,包含窗口扩展因子,可以控制窗口的大小。
(6)拥塞控制。
这里的拥塞控制是站在,接收方的角度,来控制发送方的发送速度。
就是当发送方以较慢的速度发送数据时,经过中间的链路节点的时候,未发生丢包的现象,此时A会提升窗口的大小,加快速度。相同的道理,当丢包严重时,A会降低窗口的大小,来降低A的发送速度。
(7)延时应答。
延时应答:ack不会立刻返回,而是等一段时间。
为什么要延时?目的,提升传输的效率。
延时,就是为了,给应用程序,腾出来更多的消费时间。
以次,来提高窗口的大小,提升传输的效率。
(8)捎带应答。
这是建立在延时应答的基础上,来提升速率的机制。
捎带应答在生活中也很常见,比如,叫室友帮忙带个东西等,这种都是。
日常开发中,客户端与服务端都是一问一答的情况。
如图:
如图上述所示,我们就可以把ack和响应合成一次传输,来提高传输的效率。
(9)面向字节流。
在字节流读取数据的时候,经常会发生一种问题 "粘包问题" 。就是发送的各种数据包,读取的时候,分不清结束每个数据包的初始和结束。
此时我们可以次啊用(1)使用分隔符 (2)约定包的长度 来解决以上问题。
如图:
(10)异常情况
1)其中某一个进程,突然崩溃了。
不论是进程崩溃,正常结束,操作系统都会回收对应的PCB,可以释放里面的文件描述符表,也就相当于调用了close。这里的4次挥手也能挥完。
2)某个主机关机了(正常流程的关机)。
这里和第一种情况一样,进程结束之后,进行4次挥手。
3)某个主机电源掉电。
如图例子:
B向A,发送一个心跳包,如果A没挂,就会发回一个ack,若A挂了,发送多次之后,仍没有回应,此时B就会单方面删除A的信息。
4)网线断开。
如图所示:
以上的10中机制,是面试的重点,一定要掌握。