传输控制协议TCP(Transmission Control Protocol)一种基于连接的可靠的稳定的无重复的传输协议。
1、TCP头部信息
TCP协议头部信息如下:
一共占用20个字节
- 16位源端口号:发送进程的主机端口
- 16位目的端口号:接收主机中进程的端口号
- 32为的序列号:每个包中都包含序列号,序列号被系统初始化为某个随机值ISN。后续的TCP报文段中的序列号应该加上改报文段所携带数据的第一个字节在整个字节流中的偏移。此处的报文段可以理解为字节流的一段数据包
- 32位的确认号:目的主机返回确认号,使源主机知道某个或者几个报文段已被接收
- 四位首部长度:由于TCP内包含一个长度可变的选项部分所以需要一个值来指定这个TCP报文段到底多长
- URG标志:
- ACK标志:表示确认号是否有效,携带ACK标识的TCP报文段位确认报文段
- PSH标志:
- RET标志:
- SYN标志:表示建立请求连接。携带SYN标识的TCP报文段位同步报文段
- FIN标志:标识通知对方本端要关闭连接了。携带FIN标识的TCP报文段位结束报文段
- 16位窗口大小:是TCP流量控制的一个手段。这里说的窗口指的是接受通告窗口。他告诉对方本端的TCP接收缓冲区还能容纳多少个字节的数据,这样对方就可以控制发送数据的速度。
- 16位校验和:
- 16位紧急指针:
- TCP头部选项:
2、TCP传输连接阶段
- 建立TCP连接(三次握手)
- 数据转送
- 释放TCP连接
概念区分:
三报文握手 == 三次握手/三路握手
四报文挥手 == 四次挥手/四路握手
3、TCP连接的建立
TCP建立连接需要解决三个问题:
- 双方能够知道对方的存在
- 双方能够协商一些参数(最大窗口值、是否使用窗口扩大选项、时间戳、服务质量等等)
- 双方能够对运输实体资源(例如:缓存大小、连接表中的项目等)进行分配
三次握手过程:
- 最初两端的TCP进程都处于关闭状态,客户端的某个进程主动发起TCP连接建立
- TCP服务其被动等待客户进程的TCP请求,所以TCP进入监听状态
- TCP客户端向TCP服务器进程发送TCP连接请求报文,并且进入同步已发送状态
- 请求报文的首部中的同步SYN被设置为1,表明这是一个TCP连接请求报文段,32位序列字段seq被设置了初始值,作为TCP客户端所选择的初始序号。
- TCP服务器进程接收到TCP连接请求报文段后,如果同意建立连接,则向TCP客户进程发送TCP连接请求确认报文段,并且进入同步已接收状态,该报文段首部中的同步位SYN和确认位ACK都设置为1,表明这是一个TCP连接请求确认报文段。序号字段seq被设置了一个初始值y,作为TCP服务器进进程选择的初始序号,确认号字段ack的值被设置成x+1,表明接收到了TCP客户进程序号为x的报文。
- TCP客户进程收到TCP连接请求确认报文段后,还要向TCP服务器进程发送一个普通的TCP确认报文段,并且进入连接已建立状态,报文段首部中的确认位ACK设置为1,表明这是一个普通的TCP确认报文段。序列号字段seq设置为x+1,确认号字段ack的值被设置成y+1,表明接收到了TCP服务进程序号为y的报文,TCP服务器进程收到该确认报文段后也进入连接已建立状态。
上述文字如此繁琐,可以看下图:
常见面试题:假如TCP连接的监视使用的是两次握手而不是三次可以吗?
- 假设TCP客户进程发送了一个TCP请求报文段,但是可报文段在网络结点中被长时间滞留,TCP客户采用超时重传机制重发TCP请求报文段并被TCP服务进程接收,TCP服务进程,发送一个TCP连接请求报文段确认报文段,然后TCP服务进程和客户可以进行信息传递,当数据转送完成的时候双方都处于关闭状态。
- 随后滞留在网络结点中的哪个失效的TCP请求文段,被TCP服务进程接收,TCP服务进程又发送一个TCP服务进程又发送一个TCP连接请求确认报文段,并且进入连接已建立状态,由于TCP客户进程并没有发起新的TCP连接请求,并且已经处于关闭状态了,因此不会理会TCP服务器发送的报文段,但是TCP服务器进程已经进入了连接已建立状态,他认为新的TCP连接已经建立好了,就会一直等待TCP客户进程发来数据,将会浪费TCP服务器主机的很多资源。
所以要TCP连接的建立采用三次握手:
四次挥手过程:
TCP通过四次挥手来释放连接,数据通信传输完成之后TCP双方都可以释放连接
- 假设由客户主动关闭TCP连接,
- 客户进程发送连接释放报文段 ,并且进入终止等待1状态 ,该报文段中的首部终止位FIN设置位1,ACK设置为1,表明这是一个连接释放报文段,同时也对之前接收的报文段进行确认, seq=u表示TCP客户进程之前已发送过的数据的最后一个字节的序号+1,ack=v表示客户进程之前已收到的数据的最后一个字节的序号+1。
- 服务器进程接收到TCP连接释放报文段后,会发送一个普通的TCP确认报文段并且进入关闭等待状态,此时TCP客户进程到服务器进程这个方向的连接就释放了,这时的TCP连接属于半关闭状态, 也就是TCP客户进程已经没有数据要发送了,但是TCP服务器进程如果还有数据需要发送,客户进程则还需要接收,这个状态可能会持续一段时间,直到TCP服务器进程将数据发送完毕。
- TCP客户进程收到TCP确认报文段后就进入终止等待2状态,等待TCP服务器进程发出的TCP连接释放报文段。
- 当TCP服务器进程的没有数据要发送了后,释放连接(被动关闭), FIN=1,ACK=1表明这是一个连接释放报文段,seq=w,ack=u+1同时也对之前收到的报文段进行确认。
- TCP客户进程收到TCP连接释放报文段后,必须针对该报文段发送普通的TCP确认报文段,之后进入时间等待状态。
-
TCP服务器进程收到该报文段后就进入关闭状态。
-
而TCP客户进程还需要经过2MSL后才能进入关闭状态。MSL(Maximum Segment Lifetime)意思是最长报文段寿命,RFC793建议为2分钟。
这个等待2MSL是为了保证普通的TCP确认报文段能够被TCP服务端接收到。