详解TCP协议,TCB,TCP的三次握手、四次挥手

2020-11-26  本文已影响0人  胜言_

TCP协议简介

TCP全称Transmission Control Protocol,数据传输控制协议。它是一种面向连接的、可靠的、基于字节流的传输层通信协议。

OSI:开放式系统互联模型

互联网上的数据通过应用层到物理层 层层封装(添加头部信息),由物理层传输到数据接收端,再层层解封装,最后到到达数据接收端——应用层。

常用的熟知端口号

应用程序 FTP TFTP TELNET SMTP DNS HTTP SSH MYSQL
熟知端口 21,20 69 23 25 53 80 22 3306
传输层协议 TCP UDP TCP TCP UDP TCP TCP TCP

TCB是啥?

Socket包含两部分,一个是IP地址,一个是端口号。同一个设备可以对应一个IP地址,但不同的管道用不同的端口号区分,于是同一个设备发送给其他不同设备的信息就不会产生混乱。在同一时刻,设备可能会产生多种数据需要分发给不同的设备,为了确保数据能够正确分发,TCP协议用一种叫做TCB(Transmission Control Block,传输控制块)的数据结构把发给不同设备的数据封装起来。

一个TCB数据块包含了数据发送双方对应的socket信息以及拥有装载数据的缓冲区。在两个设备要建立连接发送数据之前,双方都必须要做一些准备工作,分配内存建立起TCB数据块就是连接建立前必须要做的准备工作。我们还需要了解的一点是TCP连接的建立方式,由于TCP协议建立在服务器–客户端的模式之上,因此对于两种不同角色的设备,他们发起连接的方式不一样。

客户端发起连接的方式叫主动打开(Active Open)。也就是客户端需要主动向服务器发送消息,表达自己想建立数据连接的请求。服务器发起连接的方式叫被动打开(Passive Open),通常服务器在没有客户端主动请求的时候不知道当前有哪个设备想向它发起连接,因此它只能构建一个端口并监听该端口,等待客户端从该端口向它发起连接请求。在OPEN(打开)阶段无论是客户端还是服务器都需要准备好TCB数据结构,但由于服务器不知道要连接它的客户端的地址信息,因此在构建TCB模块时会默认将客户端对应的Socket数据初始化为0。

当客户端和服务器端双方都把自己的Socket和TCB数据结构准备好后,双方就可以进入所谓的“三次握手”TCP连接建立过程。

TCB数据结构示意

TCP的头部信息

TCP头部

TCP头部包含20个字节的固定首部和长度可变的最多40个字节的填充信息部分(可没有)。

URG:此标志表示TCP包的紧急指针域有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据;

ACK:此标志表示应答域有效,就是说前面所说的TCP确认号将会包含在TCP数据包中;ACK这个Flag有两个取值:0和1,为1的时候表示应答域有效,反之无效;

PSH:这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队;

RST:这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包;

SYN:表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送一个SYN=1,ACK=0的数据包,如果对方主机响应了一个SYN+ACK数据包回来 ,就表明这台主机存在这个端口。

FIN: 表示双方的数据传送完成,没有数据可以传送了,四次挥手,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。


TCP三次握手与四次挥手

TCP为什么要进行三次握手,而不是两次握手?

这个问题在计算机网络的教材中可以找到答案。在谢希仁著《计算机网络》第四版中讲“三次握手”的目的是,为了防止已失效的连接请求突然又传送到了服务器端,不进行第三次握手可能会产生服务器资源不必要的消耗。

试想,如果只经过两次握手即建立TCP连接会怎样?

栗子:一个已失去时间有效期的TCP连接请求报文被发送到服务器端,服务器此时并不知道这个报文在它的发送者——客户端那里已失效,服务器对这个请求报文做出回应,并切换到SYN_RCVD状态,建立TCP连接,而这个回应报文发送到客户端时,客户端并不会处理此请求,因为它发出去的请求报文早已过期,它没有处于SYN_SEND状态,而服务器误以为客户端已经处于此状态,这样就会造成服务器资源的不必要损耗,由此得出了“三次握手”建立TCP连接的方法。

通过三次握手,服务器在接收到失效请求时也是做出了回应,但这个回应(SYN/ACK包)如果在一定时间内没有收到回应,则不会建立TCP连接,资源被释放;如果服务器收到了来自客户端的回应,则建立TCP连接。

TCP的三次握手

“三次握手”的作用就是保证客户端、服务器端双方都能明确自己和对方的收、发能力是正常的。


image 三次握手

最开始的时候客户端和服务器都是处于CLOSED可用状态。开始建立TCP连接之前,服务器端的一个端口已经被动打开(passive open),用于监听来自客户端的请求,这样,客户端的端口可以主动打开(active open),发送请求到服务器端,寻求建立连接。

三次握手中的数据包只有TCP头部信息,没有主体信息。

TCP协议规定,ACK报文段(ACK标志位置1的报文)可以携带数据,但是如果不携带数据则不消耗序号,即下一个报文的序号仍为ACK报文的序号。

TCP协议规定,SYN报文段(SYN标志位置1的报文,SYN+ACK报文也属于这种情况)不能携带数据,但需要消耗掉一个序号,下一个发送的报文序号需要+1。


为什么TCP要四次挥手才能互相断开TCP连接?

简单来说,处于传输层的TCP协议是一个可靠的协议,而在它下面,处于网络层的IP(Internet Protocol,网络协议)协议是不可靠的,TCP可靠性的具体体现之一就是四次挥手,不会出现不必要的错误和资源损耗。

那四次分手又是为何呢?TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议,全双工模式。

  • 单工(Simplex)通信是指消息只能单方向传输的工作方式。例如遥控、遥测。

  • 半双工(Half Duplex)数据传输指数据可以在一个信号载体的两个方向上传输,但是不能同时传输。

  • 全双工(Full Duplex)通信允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合。

这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;但这时主机1还是可以接受来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快地断开这次TCP连接。

可以看到,如果不经过四次挥手,是不能断开连接的,因为对方那里可能还有数据没发送。只有双方互相确认(ACK)了彼此的FIN报文,TCP连接才能断开,TCP才靠得住。

TCP四次挥手

客户端和服务器端均可以发出FIN报文,即发出断开连接的请求——表示自己没有数据要发送给对方了,谁先发的谁即为主动方。

[图片上传失败...(image-308658-1606361336319)]

四次挥手

TCP规定,FIN报文段要消耗一个序号,即下一个把报文的序号需+1。

服务器结束TCP连接的时间要比客户端早一些。

FIN_WAIT_1(主动方): FIN_WAIT_1FIN_WAIT_2状态都表示等待对方的FIN报文。

这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报文后,SOCKET方进入到FIN_WAIT_2状态。

在实际情况下,无论对方何种状况,都会马上回应这个FIN一个ACK报文,所以FIN_WAIT_1状态一般是比较难捕捉到的,而FIN_WAIT_2状态常可以用netstat命令查看。

FIN_WAIT_2(主动方):FIN_WAIT_2状态下的SOCKET,表示半连接,也即主动方要求断开TCP连接,但主动方仍需要接收对方发来的FIN报文,并回应一个ACK报文。

CLOSE_WAIT(被动方):这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。

接下来你真正需要考虑的,是查看你是否还有数据发送给主动方,如果没有的话,那么你也就可以 close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是检查你还有没有数据要发给对方,没有就关闭连接,发送FIN报文告知主动方。

LAST_ACK(被动方): 是被动方在发送FIN报文后处于的一个状态,即被动方已确认无数据需要发送给主动方,可以关闭连接。

被动方最后等待主动方的ACK报文。当收到ACK报文后,被动方即进入CLOSED可用状态了。

TIME_WAIT(主动方): 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后主动方即可回到CLOSED可用状态了。

如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。(看图)

CLOSED: 表示连接已断开。

上一篇 下一篇

猜你喜欢

热点阅读