TCP连接的建立和拆除

下面将会讲一下: tcp连接的建立和拆除, 也就是三次握手四次挥手


image.png

为了保证数据的可靠传输: 通信双方都必须维护一个序列号(seq)
TCP 协议为了实现可靠传输, 通信双方需要判断自己已经发送的数据包是否都被接收方收到, 如果没收到, 就需要重发。 为了实现这个需求, 很自然地就会引出序号(sequence number) 和 确认号(acknowledgement number) 的使用。

acknowledgement number 的作用是向对方表示,我期待收到的下一个序号。 如果你向对方回复了 ack = 31, 代表着你已经收到了序号截止到30的数据,期待的下一个数据起点是 31 。
TCP 协议规定SYN报文虽然不携带数据, 但是也要消耗1个序列号, 所以前两次握手客户端和服务端都需要向对方回复 x+1 或 y+1 。

seq 确认序号其实就代表当前的序号是多少

建立连接

  • 第一步, 客户端的tcp首先向服务端的tcp发送一个特殊的tcp报文段, 该报文段不包含应用层数据, 但是在报文段的首部中的一个标志位(SYN)被置位1, 该报文段称为SYN报文段 . 另外客户会随机选择一个初始序号clent_isn, 并将此编号放置于报文段的序号字段中. 这个报文段会被封装在一个IP数据报中, 发给服务器'
    这时候客户端的状态是SYN_SENT

  • 第二步, 一旦客户端的SYN报文段到达服务器, 就会为该TCP连接分配TCP缓存和变量 (会将连接放到半连接队列中, 服务器状态变为 SYN_REVD), 并向 客户TCP发送允许连接的报文段 (这些资源就是容易受到SYN洪泛攻击). 这个允许连接的报文字段也不包含应用层数据. 不过里面有3个重要信息, SYN标记位置为1. 然后该TCP报文段的首部确认号字段设置为client_isn + 1, 然后在序号字段放入服务器自己的初始序号server_isn. 这个报文段代表的意思是同意建立连接. 这个报文段也称为 SYNACK报文段

如果半连接队列已经满了, 服务器不会将该连接状态变为SYN_RCVD, 且将这个连接丢弃

SYN flood攻击
攻击方的客户端只发送SYN分节给服务器,然后对服务器发回来的SYN+ACK什么也不做,直接忽略掉,
不发送ACK给服务器;这样就可以占据着服务器的半连接队列的资源,导致正常的客户端连接无法连接上服务器。-----[维基百科]

(SYN flood攻击的方式其实也分两种,第一种,攻击方的客户端一直发送SYN,对于服务器回应的SYN+ACK什么也不做,不回应ACK, 第二种,攻击方的客户端发送SYN时,将源IP改为一个虚假的IP, 然后服务器将SYN+ACK发送到虚假的IP, 这样当然永远也得不到ACK的回应。)

  • 第三步 在收到SYN报文段后吗客户端也需要给该连接分配缓存和变量(接收缓存这个角度之前一直没有想过, 之后遇到了可以提), 客户端则向服务起发送另外一个报文段. 这个报文段对服务器的允许连接的报文端进行确认 ( 该客户端将server_isn + 1 放入确认字段, 然后页会把自己的序号 client_isn + 1 带上 ). 因为连接已经建立, 所以该SYN标志位置为0

客户单收到SYN + ACK 后, 状态从SYN_SENT 变为ESTABLISHED, 服务端收到客户端的ACK后, 服务端状态从SYN_RCVD 变为ESTABLISHED

image.png

为什么一定要三次握手, 不能两次:
3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认
在前两次握手的时候双方都随机选择了自己的初始段序号,并且第二次握手的时候 连接请求发送端收到了自己的ACKnumber,确认了自己的序列号,而连接请求响应端还没有确认自己的序列号,没有收到ACKnumber, 如果这时候两次握手下就进行数据传递, 序号没有同步,数据就会乱序

有两个原因一方面是协商好序列号
另外一方面是防止已失效的连接请求又传送到服务器端
让两方都知道对方准备好了. 比如c和s建立tcp连接, c向s发送请求连接分组, s收到这个分组后, 发送确认应答分组. 如果只是两次握手, 那么s认为连接已经成功建立, 可以发送数据了. 但是这个确认应答信号可能在传输中会丢失, c的话也不会直到s建立什么样子的序列号, 这样子c可能会任务连接没有成功, 忽略s发来的任何数据分组, 只等待连接确认应答分组. 而s在发出的分组超时后, 会重复发送同样的分组.

连接的拆除

参与一条tcp连接的两个进程中任何一个都能终止该连接, 也就是说也可以服务端主动断开.举个例子, 假设某客户应用进程发出一个关闭连接命令. 这会引起客户Tcp向服务器进程发出特殊的tcp报文段. 这个特殊的报文段让其首部的一个FIN标志位置为1. 当服务端接收到之后,发出一个确认报文段. 之后等服务端想要终止的时候, 服务器发送它专辑的终止报文段, 其FIN标记位置为1, 最后客户端对这个服务器的终止报文段进行确认. 此时, 在两台主机上用于该链接的所有资源都释放了

image.png

image.png

image.png

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连接的时间要比客户端早一些。

问题

【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?

答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

参考博客:
https://blog.csdn.net/lengxiao1993/article/details/82771768?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id=1329187.21448.16179437351054521&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control

https://www.cnblogs.com/bj-mr-li/p/11106390.html

https://blog.csdn.net/lengxiao1993/article/details/82771768?utm_medium=distribute.pc_relevant.none-task-blog-2defaultBlogCommendFromMachineLearnPai2default-1.control&dist_request_id=1329187.21448.16179437351054521&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2defaultBlogCommendFromMachineLearnPai2default-1.control

你可能感兴趣的:(TCP连接的建立和拆除)