TCP三次握手和四次挥手

早过忘川 提交于 2019-11-26 14:24:33

常用的熟知端口号

在这里插入图片描述

TCP的概述

建立连接,每一个TCP连接都有连个端点,这种端点—>套接字(socket)。
套接字:IP+TCP协议+端口----可以标识主机进程。
例如,若IP地址为192.3.4.16 而端口号为80,那么得到的套接字为192.3.4.16:80。

TCP报文首部

TCP报文是TCP层传输的数据单元,也叫报文段。
在这里插入图片描述

  1. 端口号:用来表示同一台计算机的不同进程。
    各站2字节
    1)源端口:标识报文的返回地址。
    2)目的端口:端口指明接收方计算机上的应用程序接口。
    TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。
  2. 序号和确认号:
    序号是本报文段发送数据组的第一个字节的序号。
    确认号,即ACK,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。比如建立连接时,SYN报文的ACK标志位为0。
  3. 数据偏移/首部长度:4bits。
    因为首部含有可选字段,所以TCP报文长度是不确定的。爆头不包含任何可选字段则长度为20字节,4位首部长度字段所能表示的最大值为1111,转化为十进制为15,1532/8=60(154字节)**,所以报文头最大为60字节。**首部长度叫数据偏移,是因为首部长度实际上只是了数据区的报文段中的起始偏移值。
  4. 保留:默认0,为将来定义新的用途保留。
  5. 控制位:URG ACK PSH RST SYN FIN,共6个,每一个标志位表示一个控制功能。
    1)URG:紧急指针,为1时表示紧急指针有效,0为忽略紧急指针。
    2)ACK:确认序号标志,为1时表确认号有效,0表示报文中不含确认信息。
    3)PSH:为1时表示带有push标志的数据,只是接收方接受的数据直接交给应用程序,不再缓冲区排队了。
    4)RST:重置连接标志,用于重置由于主机崩溃或者其他原因而出现错误的连接,或者用于拒绝非法的报文段和拒绝连接请求。
    5)SYN:同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示数据段没有使用捎带的确认域,SYN=1和ACK=1
    表示连接应答捎带一个确认。
    6)FIN:finish标志,用于释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。
  6. 窗口:滑动窗口大小,用来告知发送发接收端的缓存大小,一次控制发送端发送数据的速率,从而达到流量控制,窗口大小是一个16bit字段,窗口最大为65535.
  7. 校验和:奇偶校验,对TCP整个报文段(TCP头部+TCP数据),以16位字进行计算机所得。由发送端计算和存储,并由接收端进行验证。
  8. 紧急指针:只有当URG标志为1是才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。
  9. 选项和填充:选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍
  10. 数据部分: TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。

TCP连接的建立(三次握手)

  1. TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;
  2. TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
  3. TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。
  4. TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。
  5. 当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
    在这里插入图片描述

为什么是三次不是两次握手呢?

如果出现发送端第一次发动连接请求,但是由于网络阻塞导致迟迟没有到达接收端,即发送端没有收到接收端的确认。那么发送端会再一次发送请求连接给接收端,接收端接收后发确认,建立了连接,并且传输了数据之后,段尅了连接。后来第一次的连接请求到达了接收端,接收端以为有一次连接开始了,但是此报文早就应该失效了,这样造成了不必要的资源浪费。

TCP连接释放(四次挥手)

  1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
  2. 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
  3. 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
  4. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  5. 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗ *∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
  6. 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
    在这里插入图片描述

为什么客户端最后还要等待2MSL?

MSL(Maximum Segment Lifetime最大报文段生命时间):TCP允许不同实现可以设置不同的MSL值。
1)保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能会丢失,站在服务器的角度,我已经发送了FIN+ACk报文请求断开连接,客户端没有给我回应,应该是我发送报文丢失,那么我再从新发一遍,而客户端能在2MSL时间段内收到这个重传的报文,接着做出回应报文,并且重启2MSL计数器。
2)防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

为什么建立连接是三次握手,关闭连接确是四次挥手呢?

建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP舍友几个保活计时器,每次服务器收到客户端的请求后就会中心复位这个计时器,时长一般是2小时,若2小时候内还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次,若连发送10个探测报文段仍没有反应,服务器就会认为客户端出现故障,接着就关闭连接。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!