一、这里我来说说TCP协议,要了解TCP协议我们需要了解结构。TCP协议的包头结构:
在从应用层得到数据后,会加一个TCP包头,也就是这个结构,源端口号和目标端口号就不用说了,顺序号是干嘛的?
1、序列号(顺序号)也就是这个TCP分段的编号,它的作用是用来确保TCP分段是不是乱序到达,乱序后可以通过这个序列号排序,也可以验证是否重复,这个序列号就是保证TCP可靠性的基本要求。那序列号的值是什么呢,是怎么编的号呢?实际上TCP并不是给每一个段编号,因为他是面向字节流的,所以他是对每个字节编号,这个序列号就是这个分段的第一个字节对应的编号。可以通过序列号和该段字节长度来唯一标识这个TCP分段 。
2、确认号作用就很明显,由于TCP协议是可靠地,因为它每次发生消息都会返回一个ACK段来确认接收成功,这个确认号就是接受方希望下次发送方发送的TCP分段的序列号,也就是说,我已经把这个确认号之前的的接受了。
3、头部长度:这个值只有四个字节,所以表示有限,于是规定这个值乘以4才是真实的头部长度,四个bit为最大值为15,那么头部最大为60字节,由于除了可选项之外,占20字节,可选项这个有的有有的没有,所以可选项最多占40字节,如果偏移头部长度乘以4字节后就指向数据段了。
4、控制位:保留段必须为0,至于这6个控制位:
①FIN:如果值为1,表明发送方想关闭连接
②SYN:如果值为1,说明发起连接请求
③RST:如果值为1,表明连接需要重置
④PSH:通过这个可以不让TCP缓存数据,而是直接交给应用程序
⑤ACK:如果值为1,说明有确认消息,这时确认号就有用了
⑥URG:这个值为1的话,就代表TCP分段包含紧急数据,这时紧急指针就有效了
5、窗口大小:这个就是滑动窗口用到的,值为接受窗口大小,后面慢慢说滑动窗口
6、校验和:这个是防止数据串改,有这个校验和就可以验证数据了,其他两个就不用说了
二、现在我们弄清楚了报头格式,那么就来深究TCP的运作机制,首先TCP是可靠性传输,那肯定要保证可靠性,是如何保证的呢?
1、三次握手和四次挥手,不多说,上图细看:
这里只讲重点,有个问题哈,为什么是三次握手而不是两次呢?
两次的话就代表着服务器发送后客户端不用发送ACK端来确认,这样会有两个问题:①如果服务端发送的ACK端丢失怎么办,服务端是进入连接状态了,但是客户端还在苦等啊,这样客户端超时后会在发送一个SYN给服务端,服务端以及连接了啊,又来一个咋办,所以有问题!②那第二个问题:会遭到入侵,你服务端是一直处于监听状态,我客户端主动连接,那我这个客户端是恶意的呢,我只需要发送一个SYN你就自然而然的进入连接状态,我客户端就一直发送SYN,知道把你服务端的资源全部浪费掉,你服务端就爆了啊。所以三次还是最靠谱。
这里有两个问题:
1、为什么要四次挥手,而不三次呢?
那要省略的一步就只能是接受方发送的ACK和FIN一起咯,这样也不是不可以,但是要保证接收方没有数据发送给发起方,为什么这么说呢,因为发起方要终止连接,接收方不知道啊,他突然就收到了一个FIN说要终止连接,接收方万一还有数据还要给发起方呢,可不能就这个直接掉了,于是接收方给发起方说,要的,不过你等一下,我把数据发送完,所以要先发一个ACK给发起方,过一会,没数据了才发送FIN。
2、TIME_WAIT是什么状态啊,为啥要有这个状态,就不能直接变成CLOSED状态?
这个TIME_WAIT状态很重要,我们用反证来解释,没有这个状态会怎样,如果发起方的ACK丢失了呢,接收方是不是就没办法断掉了,接收方超时重传发起方也收不了,关都关了,所以TIME_WAIT的作用就是等一段时间确保ACK到了接收方,如果丢失那接收方超时重传发起方也收的到不是,所以要有这个状态,这里还有一个作用就是要把之前的脏数据都识别并丢弃掉,因为,TCP总有一些超时重传的数据包吧,有些包可能就是阻塞掉了,但是重传的包已经被确认了不是,你这个多余的包刚好不好这时候来了,所以就要把这些包识别下,并且丢掉,免得成了无主的,不过这个功能倒不是很大,因为包有一个生命周期的,超过了就没了,不影响大局。
篇幅有限,TCP协议的滑动窗口就在后面讲。