TCP的三次握手和四次挥手,以及相关的面试问题详细解释

TCP的首部:

  TCP数据被封装在一个IP数据报中,下图中显示了TCP首部的数据格式,如果不计任选字段,他通常是20个字节。

TCP段分析:

①.16位源和目的端口号:

每个TCP段:都包含 源端 和 目的端 的端口号。(用于寻找发端和收端的应用进程)。更好实现TCP分用和复用;这两个值再加上IP首部中的 源端IP地址 和 目的端IP地址,能唯一确定一个TCP连接。

有时:一个IP地址 和 一个端口号 也称为 一个 插口(socket)

           插口对(socket pair):包含客户IP地址,客户端口号,服务器IP地址 和 服务器端口号-》 可以唯一确                                                       定互联网络中 每个TCP连接中的双方。

②.32位序号

标识:从TCP发端 向 TCP收端 发送的 数据字节流位置。表示在这个报文段中的第一个数据字节。每一个字节对应一个序号。范围(0 ~ 2^32 -1)。(指的是当前报文段的一个字节的序号。

序列号不会从0或1开始,而是建立连接时由计算机生成的一个随机数作为其初始值,通过SYN包发送给接收端主机。然后在将每转发过去的字节数累加到初始值上表示数据的位置。

③.32位确认号

期望收到下一个报文段的第一个字节序列

比如:A发送一个报文段序号为 501,数据长度为200,当B接收到501 - 700报文段。则希望下一次接受的数据序号为701.。

注意:①确认号 = N,表示到N-1为止的所有数据都正确收到。

④URG ...等

这里写图片描述

这里写图片描述

⑤16位窗口

占两个字节。窗口值的范围是【0,2^16 -1】之间的整数(65535)。

TCP提供一种流量控制机制。

窗口指的是:发送本报文段的一方的接收窗口,(而不是自己的发送窗口)。

窗口值:告诉对方-》从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。总之,窗口值作为接受方让发送方设置其发送窗口的依据。

⑥校验和

占两个字节。

校验 覆盖了整个TCP报文段:TCP首部 和 TCP数据。

这是一个强制性的字段。一定是由发端计算和存储;并由收端进行验证。

在计算校验和时:要在TCP报文段前面加上12个字节的伪首部。

⑦4位的数据偏移 最大表示为 1 1 1 1(15)。其单位为4个字节。也就是15*4 = 60
⑧16位的紧急指针

两个字节。紧急指针仅在URG = 1时才有意义。

他指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据)。因此紧急指针指出了紧急数据的末尾在报文段中的位置。当all紧急数据都处理完时,TCP就告诉应用程序恢复到正常操作。

值得注意的是:及时窗口为0时,也可以发送紧急数据。

⑨保留位 设置为0

三次握手和四次挥手

  1.序列号seq

    占四个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上了一个序号,第一个字节的编号有本地随机产生,给字节编上序号之后,就给每一个报文段指派一个序号,序列号seq就是这个报文段中的第一个字节的数据编号。

  2.确认号

    占四个字节,期待收到对方下一个报文段的第一个数据字节的序号,序列号表示报文段携带数据的第一个字节编号,而确认号指的是期望接收到下一个字节的编号,因此报文段的最后一个字节的编号+1就是确认号。

  3.确认ACK

    占以为bit位,仅当ACK = 1,确认号字段才有效。

  4.通步SYN

    连接建立时用于同步序号。当SYN = 1,ACK = 0表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使用SYN = 1,ACK = 1。因此SYN = 1表示一个连接请求,或连接接收报文。SYN这个标志位只有在YCP建立连接才会被设置为1,握手完成后SYN被设置为0

  5.终止FIN

    用来释放一个TCP连接

对服务而言,刚开始他建立套接字,执行绑定,监听函数之后处于Listen状态,等待客户端发送请求,进行相应的响应。

三次握手过程分析:

①第一次握手

  建立连接时:客户端发送了SYN包到服务器,其中包含客户端的初始序号seq = x,并进入SYN_SENT状态,等待服务器确认。(SYN = 1 , ACK = 0.表示这是一个TCP连接请求数据报文;序号seq = x,表明传输数据时的第一个数据字节的序号是x)。

②第二次握手

  服务器接收到请求之后,必须确认客户的数据包。同时字节也发送了一个SYN包,即SYN+ACK包,此时服务器进入SYN_RECV状态。(确认报文段:标识位SYN = 1,ACK = 1,并且含有服务器的初始序号seq(服务器)= y,以及服务器对客户端初始序号的确认号ack(服务器)= seq(客户端) + 1 = x +1)

③第三次握手

  客户端接受到服务器的SYN + ACK包,向服务器发送一个序列号(seq = x +1)确认号ack(客户端)=y + 1,此包发送完毕,客户端和服务器进入ESTAB_LISHED(TCP连接成功状态)

常见的面试问题:

  1.为什么需要三次握手,两次可以吗?或者四次,五次可以吗?

    情况1.两次握手:

    客户端发出SYN,客户端发出ACK。这样会导致一种情况服务器给客户端回ACK确认报文段时,发生了数据丢失,那么客户端就会进行重传。这样会导致服务器会产生多个无效连接,占用资源,导致服务器瘫痪--》“SYN的洪水攻击”。

    由于网络问题,客户端发送的SYN都滞留在了中途,导致超时重传。同样服务器端会接收到很多的SYN,导致很多的无效连接。

总结:第三次握手为了防止:如果客户端迟迟没有收到服务器返回的确认报文,这时会放弃连接,重新启动一条连接请求,但问题是服务器不知道客户端没有收到,所以服务器会收到多个连接,浪费连接开销。

  情况2.四次握手:

    也就是将第二次握手的ACK和SYN分开发送,这样一来会导致时间效率的降低,发了多个包资源,以及多于包占用了发送和接受的缓冲区。

但是他可以成功的建立连接。

四次挥手过程分析(假设客户端为关闭主动方)

①第一次挥手:

  首先,客户端发送一个FIN,请求关闭客户端到服务器的数据传输,然后等待服务器的确认。其中终止标志位FIN = 1,序列号seq = u。客户端处于FIN_WAIT_1状态。

②第二次挥手:

  服务器收到这个FIN,他立即发送一个ACK确认报文段,确认ack为收到序号加1,同时发送一个自己的序号为seq = v.。服务器进入CLOSE_WAIT状态。

此时TCP服务器进程进入就通知高层应用进程,因而从客户端到服务器的连接就释放了。此时是“半关闭状态”,即客户端不可以发送数据给服务器,但服务器可以发送给客户端。

③第三次挥手:

  此时如果服务器没有数据报发送给客户端,其应用程序就会通知TCP释放连接,然后服务器发送一个FIN给客户端,此时服务器处于LAST_ACK状态。

④第四次挥手

  客户端收到FIN后,并发会了一个ACK确认报文段,此时服务器直接close,而客户端进入TIME_WAIT状态,等待2MSL时间。再进入CLOSE状态。

面试常问问题:

1.为什么主动关闭方最后需要2MSL的时间

  首先,2MSL(Maximum Segment LifeTime),就是最大报文生存时间,是任何报文在网络中存在的最长时间,超过这个时间报文将被丢弃。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟,2分钟等。

  等待2MSL的目的是:防止最后一个ACK包对方没有收到。如果没有等待时间,发送完确认报文段就立即释放连接的话,服务器将无法重传,因此也就收不到确认,就无法按步骤进入CLOSE状态,即服务器必须收到确认后,客户端才能CLOSE。

TIME_WAIT状态时两端的端口都不能使用,要等2MSL时间结束才能继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。防止了已经失效的连接请求报文出现在连接中,在该时间内,产生的所有报文段就可以都从网络中消失。

2.为什么是四次挥手,而不是三次或者五次,六次?

  双方关闭连接,要经过双方的同意。所以,首先是客户端给服务器发送FIN,要求关闭连接,服务器接收到会发送一个ACK进行确认。服务器然后在发送一个FIN,客户端发送ACK进行确认,并进入TIME_WAIT状态,等待2MSL之后自动关闭。

猜你喜欢

转载自blog.csdn.net/genzld/article/details/84139537
今日推荐