TCP/IP ,三次握手和四次挥手
ietf介绍TCP的文档--1981年 TCP-tutorialrfc3168 更改后flag为8位添加了ECE、CWRrfc3540 实验性的改为9位,添加了NS除了ACK flag之外 其他flag均会占用一个seq号四次挥手也可以是三次挥手 被断开方 的两次合成一次,参见TCPdump例子 http80win sshwinwin ssh Linux 对应加了S参数 seq和ack 都是绝对值不是相对值《TCP/IP详解卷1 18.2.5》http80其他参照https://www.jianshu.com/p/29868fb82890https://en.wikipedia.org/wiki/Transmission_Control_Protocolhttps://zh.wikipedia.org/zh-cn/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE

一文搞懂TCP的三次握手和四次挥手
TCP的三次握手和四次挥手实质就是TCP通信的连接和断开。 三次握手:为了对每次发送的数据量进行跟踪与协商,确保数据段的发送和接收同步,根据所接收到的数据量而确认数据发送、接收完毕后何时撤消联系,并建立虚连接。四次挥手:即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。TCP三次握手、四次挥手时序图TCP协议位于传输层,作用是提供可靠的字节流服务,为了准确无误地将数据送达目的地,TCP协议采纳三次握手策略。三次握手原理:第1次握手:客户端发送一个带有SYN(synchronize)标志的数据包给服务端;第2次握手:服务端接收成功后,回传一个带有SYN/ACK标志的数据包传递确认信息,表示我收到了;第3次握手:客户端再回传一个带有ACK标志的数据包,表示我知道了,握手结束。其中:SYN标志位数置1,表示建立TCP连接;ACK标志表示验证字段。可通过以下趣味图解理解三次握手:三次握手过程详细说明:1、客户端发送建立TCP连接的请求报文,其中报文中包含seq序列号,是由发送端随机生成的,并且将报文中的SYN字段置为1,表示需要建立TCP连接。(SYN=1,seq=x,x为随机生成数值);2、服务端回复客户端发送的TCP连接请求报文,其中包含seq序列号,是由回复端随机生成的,并且将SYN置为1,而且会产生ACK字段,ACK字段数值是在客户端发送过来的序列号seq的基础上加1进行回复,以便客户端收到信息时,知晓自己的TCP建立请求已得到验证。(SYN=1,ACK=x+1,seq=y,y为随机生成数值)这里的ack加1可以理解为是确认和谁建立连接;3、客户端收到服务端发送的TCP建立验证请求后,会使自己的序列号加1表示,并且再次回复ACK验证请求,在服务端发过来的seq上加1进行回复。(SYN=1,ACK=y+1,seq=x+1)。由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。四次挥手原理:第1次挥手:客户端发送一个FIN,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1状态;第2次挥手:服务端收到FIN后,发送一个ACK给客户端,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),服务端进入CLOSE_WAIT状态;第3次挥手:服务端发送一个FIN,用来关闭服务端到客户端的数据传送,服务端进入LAST_ACK状态;第4次挥手:客户端收到FIN后,客户端t进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,服务端进入CLOSED状态,完成四次挥手。其中:FIN标志位数置1,表示断开TCP连接。可通过以下趣味图解理解四次挥手:四次挥手过程详细说明:1、客户端发送断开TCP连接请求的报文,其中报文中包含seq序列号,是由发送端随机生成的,并且还将报文中的FIN字段置为1,表示需要断开TCP连接。(FIN=1,seq=x,x由客户端随机生成);2、服务端会回复客户端发送的TCP断开请求报文,其包含seq序列号,是由回复端随机生成的,而且会产生ACK字段,ACK字段数值是在客户端发过来的seq序列号基础上加1进行回复,以便客户端收到信息时,知晓自己的TCP断开请求已经得到验证。(FIN=1,ACK=x+1,seq=y,y由服务端随机生成);3、服务端在回复完客户端的TCP断开请求后,不会马上进行TCP连接的断开,服务端会先确保断开前,所有传输到A的数据是否已经传输完毕,一旦确认传输数据完毕,就会将回复报文的FIN字段置1,并且产生随机seq序列号。(FIN=1,ACK=x+1,seq=z,z由服务端随机生成);4、客户端收到服务端的TCP断开请求后,会回复服务端的断开请求,包含随机生成的seq字段和ACK字段,ACK字段会在服务端的TCP断开请求的seq基础上加1,从而完成服务端请求的验证回复。(FIN=1,ACK=z+1,seq=h,h为客户端随机生成)至此TCP断开的4次挥手过程完毕。LISTEN:等待从任何远端TCP 和端口的连接请求。SYN_SENT:发送完一个连接请求后等待一个匹配的连接请求。SYN_RECEIVED:发送连接请求并且接收到匹配的连接请求以后等待连接请求确认。ESTABLISHED:表示一个打开的连接,接收到的数据可以被投递给用户。连接的数据传输阶段的正常状态。FIN_WAIT_1:等待远端TCP 的连接终止请求,或者等待之前发送的连接终止请求的确认。FIN_WAIT_2:等待远端TCP 的连接终止请求。CLOSE_WAIT:等待本地用户的连接终止请求。CLOSING:等待远端TCP 的连接终止请求确认。LAST_ACK:等待先前发送给远端TCP 的连接终止请求的确认(包括它字节的连接终止请求的确认)TIME_WAIT:等待足够的时间过去以确保远端TCP 接收到它的连接终止请求的确认。TIME_WAIT 两个存在的理由:1.可靠的实现tcp全双工连接的终止;2.允许老的重复分节在网络中消逝。 CLOSED:不在连接状态(这是为方便描述假想的状态,实际不存在)。

网络 之 三次握手&四次挥手 介绍
要了解三次握手&四次挥手的过程,就需要对TCP的报头以及有限状态机的概念有所了解,本文将介绍TCP报头的字段的含义,以及有限状态机各个状态的意义,最后对三次握手和四次挥手的过程做介绍 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内另一个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。这里将介绍TCP报头的特性以及TCP报头各个字段的含义.工作在传输层面向连接协议.全双工协议.半关闭.错误检查.将数据打包成段,排序.确认机制.数据恢复,重传.流量控制,滑动窗口.拥塞控制,慢启动和拥塞避免算法.源端口、目标端口 :计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口某个时刻只能被一个进程占用,所以通过指定源端口和目标端口,就可以知道是哪两个进程需要通信。源端口、目标端口是用16位表示的,可推算计算机的端口个数为2^16个. 序列号 :表示本报文段所发送数据的第一个字节的编号。在TCP连接中所传送的字节流的每一个字节都会按顺序编号。由于序列号由32位表示,所以每2^32个字节,就会出现序列号回绕,再次从0 开始. 确认号 :表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。也就是告诉发送发:我希望你(指发送方)下次发送的数据的第一个字节数据的编号是这个确认号. 数据偏移 :表示TCP报文段的首部长度,共4位,由于TCP首部包含一个长度可变的选项部分,需要指定这个TCP报文段到底有多长。它指出TCP 报文段的数据起始处距离TCP 报文段的起始处有多远。该字段的单位是32位(即4个字节为计算单位),4位二进制最大表示15,所以数据偏移也就是TCP首部最大60字节. URG :表示本报文段中发送的数据是否包含紧急数据。后面的紧急指针字段(urgent pointer)只有当URG=1时才有效. ACK :表示是否前面的确认号字段是否有效。ACK=1,表示有效。只有当ACK=1时,前面的确认号字段才有效。TCP规定,连接建立后,ACK必须为1,带ACK标志的TCP报文段称为确认报文段. PSH :提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间。如果为1,则表示对方应当立即把数据提交给上层应用,而不是缓存起来,如果应用程序不将接收到的数据读走,就会一直停留在TCP接收缓冲区中. RST :如果收到一个RST=1的报文,说明与主机的连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。或者说明上次发送给主机的数据有问题,主机拒绝响应,带RST标志的TCP报文段称为复位报文段. SYN :在建立连接时使用,用来同步序号。当SYN=1,ACK=0时,表示这是一个请求建立连接的报文段;当SYN=1,ACK=1时,表示对方同意建立连接。SYN=1,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中SYN才置为1,带SYN标志的TCP报文段称为同步报文段. FIN :表示通知对方本端要关闭连接了,标记数据是否发送完毕。如果FIN=1,即告诉对方:“我的数据已经发送完毕,你可以释放连接了”,带FIN标志的TCP报文段称为结束报文段. 窗口大小 :表示现在充许对方发送的数据量,也就是告诉对方,从本报文段的确认号开始允许对方发送的数据量. 校验和 :提供额外的可靠性. 紧急指针 :标记紧急数据在数据字段中的位置. 选项部分 :其最大长度可根据TCP首部长度进行推算。TCP首部长度用4位表示,选项部分最长为:(2^4-1)*4-20=40字节常见选项 :.最大报文段长度:MaxiumSegment Size,MSS.窗口扩大:Windows Scaling.时间戳:Timestamps.a 最大报文段长度指明自己期望对方发送TCP报文段时那个数据字段的长度。默认是536字节。数据字段的长度加上TCP首部的长度才等于整个TCP报文段的长度。MSS不宜设的太大也不宜设的太小。若选择太小,极端情况下,TCP报文段只含有1字节数据,在IP层传输的数据报的开销至少有40字节(包括TCP报文段的首部和IP数据报的首部)。这样,网络的利用率就不会超过1/41。若TCP报文段非常长,那么在IP层传输时就有可能要分解成多个短数据报片。在终点要把收到的各个短数据报片装配成原来的TCP报文段。当传输出错时还要进行重传,这些也都会使开销增大。因此MSS应尽可能大,只要在IP层传输时不需要再分片就行。在连接建立过程中,双方都把自己能够支持的MSS接入这一字段。MSS只出现在SYN报文中。即:MSS出现在SYN=1的报文段中.b 窗口扩大为了扩大窗口,由于TCP首部的窗口大小字段长度是16位,所以其表示的最大数是65535。但是随着时延和带宽比较大的通信产生(如卫星通信),需要更大的窗口来满足性能和吞吐率,所以产生了这个窗口扩大选项.c 时间戳可以用来计算RTT(往返时间),发送方发送TCP报文时,把当前的时间值放入时间戳字段,接收方收到后发送确认报文时,把这个时间戳字段的值复制到确认报文中,当发送方收到确认报文后即可计算出RTT。也可以用来防止回绕序号PAWS,也可以说可以用来区分相同序列号的不同报文。因为序列号用32为表示,每2^32个序列号就会产生回绕,那么使用时间戳字段就很容易区分相同序列号的不同报文2.3 TCP协议PORT.传输层通过port号,确定应用层协议.Port number:. tcp :0-65535,传输控制协议,面向连接的协议;通信前需要建立虚拟链路;结束后拆除链路.. udp :0-65535,User Datagram Protocol,无连接的协议.. IANA :互联网数字分配机构(负责域名,数字资源,协议分配)0-1023:系统端口或特权端口(仅管理员可用) ,众所周知,永久的分配给固定的系统应用使用,22/tcp(ssh), 80/tcp(http), 443/tcp(https)1024-49151:用户端口或注册端口,但要求并不严格,分配给程序注册为某应用使用,1433/tcp(SqlServer),1521/tcp(oracle),3306/tcp(mysql),11211/tcp/udp(memcached)49152-65535:动态端口或私有端口,客户端程序随机使用的端口其范围的定义:/proc/sys/net/ipv4/ip_local_port_range有限状态机,(英语:Finite-state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。常见的计算机就是使用有限状态机作为计算模型的:对于内存的不同状态,CPU通过读取内存值进行计算,更新内存中的状态。CPU还通过消息总线接受外部输入设备(如键盘、鼠标)的指令,计算后更改内存中的状态,计算结果输出到外部显示设备(如显示器),以及持久化存储在硬盘。TCP协议也存在有限状态机的概念,TCP 协议的操作可以使用一个具有 11 种状态的有限状态机来表示.CLOSED 没有任何连接状态.LISTEN 侦听状态,等待来自远方TCP端口的连接请求.SYN-SENT 在发送连接请求后,等待对方确认.SYN-RECEIVED 在收到和发送一个连接请求后,等待对方确认.ESTABLISHED 代表传输连接建立,双方进入数据传送状态.FIN-WAIT-1 主动关闭,主机已发送关闭连接请求,等待对方确认.FIN-WAIT-2 主动关闭,主机已收到对方关闭传输连接确认,等待对方发送关闭传输连接请求.TIME-WAIT 完成双向传输连接关闭,等待所有分组消失.CLOSE-WAIT 被动关闭,收到对方发来的关闭连接请求,并已确认.LAST-ACK 被动关闭,等待最后一个关闭传输连接确认,并等待所有分组消失.CLOSING 双方同时尝试关闭传输连接,等待对方确认.客户端通过connect系统调用主动与服务器建立连接connect系统调用首先给服务器发送一个同步报文段,使连接转移到SYN_SENT状态。.此后connect系统调用可能因为如下两个原因失败返回:.1、如果connect连接的目标端口不存在(未被任何进程监听),或者该端口仍被处于TIME_WAIT状态的连接所占用(见后文),则服务器将给客户端发送一个复位报文段,connect调用失败。.2、如果目标端口存在,但connect在超时时间内未收到服务器的确认报文段,则connect调用失败。.connect调用失败将使连接立即返回到初始的CLOSED状态。如果客户端成功收到服务器的同步报文段和确认,则connect调用成功返回,连接转移至ESTABLISHED状态.当客户端执行主动关闭时,它将向服务器发送一个结束报文段FIN,同时连接进入FIN_WAIT_1状态。若此时客户端收到服务器专门用于确认目的的确认报文段,则连接转移至FIN_WAIT_2状态。当客户端处于FIN_WAIT_2状态时,服务器处于CLOSE_WAIT状态,这一对状态是可能发生半关闭的状态。此时如果服务器也关闭连接(发送结束报文段),则客户端将给予确认并进入TIME_WAIT状态.客户端从FIN_WAIT_1状态可能直接进入TIME_WAIT状态(不经过FIN_WAIT_2状态),前提是处于FIN_WAIT_1状态的服务器直接收到带确认信息的结束报文段(而不是先收到确认报文段,再收到结束报文段)注意,客户端先发送一个FIN给服务端,自己进入了FIN_WAIT_1状态,这时等待接收服务端的报文,该报文会有三种可能:a 只有服务端的ACK,只收到服务器的ACK,客户端会进入FIN_WAIT_2状态,后续当收到服务端的FIN时,回应发送一个ACK,会进入到TIME_WAIT状态,这个状态会持续2MSL(TCP报文段在网络中的最大生存时间,RFC 1122标准的建议值是2min).客户端等待2MSL,是为了当最后一个ACK丢失时,可以再发送一次。因为服务端在等待超时后会再发送一个FIN给客户端,进而客户端知道ACK已丢失b 只有服务端的FIN,回应一个ACK给服务端,进入CLOSING状态,然后接收到服务端的ACK时,进入TIME_WAIT状态c 同时收到服务端的ACK和FIN,直接进入TIME_WAIT状态.收到服务器ACK后,客户端处于FIN_WAIT_2状态,此时需要等待服务器发送结束报文段,才能转移至TIME_WAIT状态,否则它将一直停留在这个状态。如果不是为了在半关闭状态下继续接收数据,连接长时间地停留在FIN_WAIT_2状态并无益处。连接停留在FIN_WAIT_2状态的情况可能发生在:客户端执行半关闭后,未等服务器关闭连接就强行退出了。此时客户端连接由内核来接管,可称之为孤儿连接(和孤儿进程类似)。.Linux为了防止孤儿连接长时间存留在内核中,定义了两个内核参数:./proc/sys/net/ipv4/tcp_max_orphans 指定内核能接管的孤儿连接数目./proc/sys/net/ipv4/tcp_fin_timeout指定孤儿连接在内核中生存的时间TCP协议中的三次握手和四次挥手客户机端的三次握手和四次挥手服务器端的三次握手和四次挥手1 client 首先发送一个连接试探,此时ACK=0,表示确认号无效,SYN=1表示这是一个请求连接或连接接受报文,同时表示这个数据包不携带数据,seq=x表示此时client自己数据的初始序号是x,这时候client进入syn_sent状态,表示客户端等等服务器的回复2 server 监听到连接请求报文后,如同意建立连接,则向client发送确认,将TCP报文首部的SYN和ACK都置为1,因为client上一个请求连接的报文中seq=x,所以服务器端这次就发ack=x+1,表示服务器端希望客户端下一个报文段的第一个数据字节序号是x+1,同时表示x为止的所有数据都已经正确收到了,其中,此时服务器端发送seq=y表示server自己的初始序号是y,这时服务器进入了SYN_RCVD状态,表示服务器已经收到了客户端的请求,等待client的确认。3 client收到确认后还要再次给服务器端发送确认,同时携带要发给server的数据。ACK=1表示确认号ack=y+1有效,client这时的序号seq为x+1一旦client确认后,这个TCP连接的client 和 server 都直接进入到established状态,可以发起http请求了4.2 四次挥手详解第一次挥手:client向server,发送FIN报文段,表示关闭数据传送,此时ACK=0,seq=u,表示客户端此时数据的报文序号是u,此时,client进入FIN_WAIT_1状态,表示没有数据要传输了第二次挥手:server收到FIN报文段后进入CLOSE_WAIT状态(被动关闭),然后发送ACK确认,表示同意你关闭请求了,主机到主机的数据链路关闭,同时发送seq=v,表示此时server端的数据包字节序号是v,ack=u+1,表示希望client发送的下一个包的序号是u+1,表示确认了序号u之前的包都已经收到,客户端收到server的ACK报文后,进入FIN_WAIT_2状态第三次挥手:server等待client发送完数据,发送FIN=1,ACK=1到client请求关闭,server进入LAST_ACK状态。此时发送的seq有变化,因为上一个ACK的后server端可能又发送了一些数据,说以数据字节序号发送了变化,为w,但是ack还是保持不变第四次挥手:client收到server发送的FIN后,回复ACK确认到server,client进入TIME_WAIT状态。发送ack=w+1,表示希望服务器下个发送的报文的字节序号是w+1,确认了服务器之前发送的w字节都已经正确收到,发送seq=u+1表示当前client的字节序号是u+1.server收到client的ACK后就关闭连接了,状态为CLOSED。client等待2MSL,仍然没有收到server的回复,说明server已经正常关闭了,client关闭连接。其中,MSL(Maximum Segment Lifetime):报文最大生存时间,是任何报文段被丢弃前在网络内的最长时间。当client回复server的FIN后,等待(2-4分钟),即使两端的应用程序结束。TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态的原因是如果client直接进入CLOSED状态,由于IP协议不可靠性或网络问题,导致client最后发出的ACK报文未被server接收到,那么server在超时后继续向client重新发送FIN,而client已经关闭,那么找不到向client发送FIN的连接,server这时收到RST并把错误报告给高层,不符合TCP协议的可靠性特点。如果client直接进入CLOSED状态,而server还有数据滞留在网络中,当有一个新连接的端口和原来server的相同,那么当原来滞留的数据到达后,client认为这些数据是新连接的。等待2MSL确保本次连接所有数据消失。 当客户端等待2MSL后服务器端没有再次发送确认的报文后,client认为该次断开连接已经正常结束,client进入closed状态。四次挥手正式结束

三次握手&&四次挥手
TCP是面向连接的协议。传输连接是用来传送TCP报文的,TCP连接传输的三个阶段分别为:连接建立、数据传送和连接释放。TCP连接的建立采用客户服务器模式。主动发起连接建立的应用进程叫做客户,而被动等待连接建立的应用进程叫做服务器。TCP建立连接的过程叫做握手,握手需要在客户和服务器之间交换三个TCP报文段,三次握手的过程如下图所示。(2)第二次握手:服务器收到 SYN报文段后,如同意连接,则服务器会为该TCP连接分配缓存和变量,并向客户端返回确认报文段,在确认报文段中同步位 SYN = 1 和 确认位 ACK= 1,确认号 ack = x + 1,同时也为自己选择一个初始序号 seq = y。这时TCP服务器进程进入同步收到(SYN-RCVD)状态。(3)第三次握手:客户进程在收到服务器进程的确认报文后,客户端为该TCP连接分配缓存和变量,并向服务器端返回一个报文段,这个报文段是对服务器确认报文段进行确认,该报文段中 ACK = 1,确认号 seq = y + 1,而自己序号为 x + 1(即第二次握手服务器确认报文段的确认号)。客户端在发送ACK报文段后进入已建立连接(ESTABLISHED)状态,这时TCP连接已经建立。当服务器收到客户端的确认后,也进入ESTABLISHED状态。这样选择序号的目的是为了防止由于网络路由TCP报文段可能存在延迟抵达与排序混乱的问题,从而而导致某个连接的一方对它作错误的解释。下图表示了建立连接使用固定的序号存在的问题:由于一个TCP连接是被一对端点所表示的,其中包括2个IP地址和2个端口号构成的4元组,因此即便是同一个连接也会出现不同的实例,如果连接由于某个报文段长时间延迟而关闭,然后又以相同的4元组被重新打开,那么可以相信延迟的报文段又会被视为有效据重新进入新连接的数据流中,这就会导致数据乱序问题。为了避免上述的问题,避免连接实例间的序号重叠可以将风险降至最低。如前文所述,一个TCP报文段只有同时具备连接的4元组与当前活动窗口的序列号,才会在通信过程中被对方认为是正确的。然而,这也反应了TCP连接的脆弱性:如果选择合适的序列号、IP地址和端口号,那么任何人都能伪造一个TCP报文段,从而打断TCP的正常连接。所以使用初始化序号的方式(通常随机生成序号)使得序列号变得难猜,或者使用加密来避免利用这种缺点被攻击。所以,可以明白在建立TCP连接时,客户端和服务器端初始化序列号,就避免了上述的问题。前面说过,TCP序号占32位,范围是0~232- 1,并且可以重用。假如 第一次握手可以携带数据的话,如果有人使用伪TCP报文段恶意攻击服务器,那么每次都在第一次握手中的SYN报文中携带大量的数据,因为它不会理会服务器的发送和接收能力是否正常,不断地给服务器重复发送这样携带大量数据的SYN报文,这会导致服务器需要花费大量的时间和内存来接收这些报文数据,这会将导致服务器连接资源和内存消耗殆尽。所以,之所以第一次握手不能携带数据,其中的一个原因就是避免让服务器受到攻击。而对于第三次握手,此时客户端已经建立了连接,通过前两次已经知道了服务器的接收正常,并且也知道了服务器的接收能力是多少,所以可以携带数据。根据前面描述,在第一次握手,客户端向服务发送建立连接请求,第二次握手,服务器同意建立连接,并向客户端返回一个确认报文,至此客户端已经知道了服务器同意建立连接,为什么客户端还需要对服务器的允许连接报文段进行确认?第三个ACK报文段的目的简单来说主要是为了实现可靠数据传输。三次握手的目的不仅在于让通信双方了解一个连接正在建立,还在于利用数据包的选项来承载特殊的信息,交换初始序列号(Initial Sequence,ISN)。为了实现可靠传输,TCP协议通信双方,都必须维护一个序列号,以标识发送出去的数据报中,哪些是已经被对方收到的。三次握手的过程是通信双方想要告知序列号起始值,并确认已经收到序列号的必经过程。如上图,在两次握手过程中,通信双方都随机选择了自己的初始段序号,并且第二次握手的时候客户端收到了自己的确认序号,确认了自己的序列号,而服务器端还没有确认自己的序列号,没有收到确认序号, 如果这时候两次握手下就进行数据传递, 序号没有同步,数据就会乱序。即如果只是两次握手,最多只有客户端的起始序列号能被确认,而服务器断的序列号则得不到确认。在三次握手的过程中,服务器为了响应一个受到的SYN报文段,会分配并初始化连接变量和缓存,然后服务器发送一个SYNACK报文段进行响应,并等待客户端的ACK报文段。如果客户不发送ACK来完成该三次握手的第三步,最终(通常在一分多钟之后)服务器将终止该半开连接并回收资源。这种TCP连接管理协议的特性就会有这样一个漏洞,攻击者发送大量的TCP SYN报文段,而不完成第三次握手的步骤。随着这种SYN报文段的不断到来,服务器不断为这些半开连接分配资源,从而导致服务器连接资源被消耗殆尽。这种攻击就是SYN泛供攻击。为了应对这种攻击,现在有一种有效的防御系统,称为SYN cookie。SYN cookie的工作方式如下:连接释放的四次挥手过程如下图所示:(2)第二次挥手:服务器收到连接释放报文段后即发出确认,确认为ACK = 1,确认号为ack = u + 1,序号seq = v(其值是服务器前面已传送过的数据最后一个字节的序号加1),然后服务器就进入了关闭等待(CLOSE-WAIT)状态。(3)第三次挥手:如果此时服务器没有数据要发送了,此时服务器向客户端发出连接释放报文段,其FIN = 1,假设器序号为seq = w(在半关闭状态下服务器可能又发送了一些数据),服务器必须重复上次以发送的确认号ack = u + 1(因为客户端没有向服务器发送过数据,所以确认号和上次一致)。这时,服务器进入最后确认(LAST-ACK)状态,等待客户端的确认。(4)第四次挥手:客户端在收到服务器端发出的连接释放报文段后,必须对此发出确认,在确认报文段中将ACK置位1,确认号ack = w + 1,而自己的序号为seq = u + 1。之后客户端进入时间等待(TIME-WAIT)状态。在经过时间等待计时器设置的时间2MSL后,客户端才进入关闭(CLOSE)状态这是为了保证客户端发送的最后一个ACK报文段能够到达服务器端。客户端发送的ACK报文段可能丢失,因而使服务器收不到对自己已发送的释放连接报文段的确认。服务器会重传连接释放报文段,重新启动2MSL计时器,最终,客户端和服务器端都能进入CLOSE状态。在建立连接时,服务器端处于LISTEN状态时,当收到SYN报文段的建立连接请求后,它可以把ACK报文段和SYN报文段(ACK报文段起确认作用,即确认客户端的连接建立请求;SYN报文段起同步作用)放在一起发送,所以在连接建立时四次握手(即第二次握手时,服务器的ACK报文段和SYN报文段分开发送)可以合并为三次握手。而在释放连接时需要四次是因为TCP连接的半关闭造成的。由于TCP是全双工的(即数据可在两个方向上同时传递),因此,每个方向都必须要单独进行关闭,这个单方向的关闭就叫半关闭。在关闭连接时,当服务器收到客户端的FIN报文通知时,它仅仅表示客户端没有数据发送服务器了;但服务器未必将所有的数据都全部发送给了客户端,所以服务器端未必马上也要关闭连接,也即服务器端可能还需要发送一些数据给客户端之后,再发送FIN报文给客户端来表示现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的,这也是为什么释放连接时需要交换四次报文了。

TCP和UDP的区别(三次握手四次挥手全过程图解)
首先OSI有七层模型,从上往下依次是应用层、表示层、会话层、传输层、网络层、数据链路层、物理层,而TCP/UDP则属于传输层1、TCP和UDP的区别一般我们进行网络通信时,会使用TCP/UDP进行通信,那么我们首先介绍下TCP和UDP到底有什么区别,应用场景又有什么区别?TCP是一种面向连接,可靠稳定的传输协议,建立连接需要经历三次握手,握手成功才可通信,但是速度比较慢,效率比较低,容易被DOS,DDOS攻击。UDP是一种面向无连接,不可靠的传输协议,会直接建立连接,速度快,没有三次握手的机制,所以会相对安全,但是UDP还是可能会被flood攻击,在网络不好的情况,容易发生丢包。2、那么TCP又是如何准确无误的传输数据的呢?当客户端与服务器通过三次握手建立了TCP连接过后,当数据传送完毕,相应的就要断开TCP连接了,于是就有了四次分手的步骤。TCP头部:ACK : TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1SYN:当SYN为1时,表明此数据包是一个同步包,用来表明正在请求连接。可能会形成死锁。假设客户端给服务器发送了一个连接请求报文,服务端成功接收并给客户端发送了确认应答报文,此时服务端并不能确认该应答报文是否成功到了客户端,但因为两次握手,所以这时候服务端就处于成功连接的状态了,并给客户端发送数据。如果客户端未收到服务端的应答报文,则不知道服务器是否确认好建立连接,甚至不知道自己发送给服务器的报文是否成功抵达,此时客户端会认为连接并未成功建立,会忽略服务端发送过来的任何数据。而服务端发送的数据未得到相应超时时,会重复发送同样的数据,这样就形成了死锁。(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,我们也未必全部数据都发送给对方了,所以我们不可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,我们的ACK和FIN一般都会分开发送。

本文由 在线网速测试 整理编辑,转载请注明出处,原文链接:https://www.wangsu123.cn/news/301880.html。