TCP的三次握手、四次挥手--非常详细讲解

TCP的三次握⼿、四次挥⼿--⾮常详细讲解
本篇⽂章转⾃ 不过进⾏了⼀些编辑。
TCP(Transmission Control Protocol) 传输控制协议
1、TCP和四次挥⼿的过程图
tcp的6种标志位的分别代表: SYN(synchronous建⽴联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束)
RST(reset重置) URG(urgent紧急) Sequence number(顺序号码) Acknowledge number(确认号码) 客户端TCP状态迁移:CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED服务器TCP状态迁移:CLOSED->LISTEN->SYN 收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED 各个状态的意义如下: 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接收到连接中断请求的确认; CLOSED - 没有任何连接状态; 下⾯具体说说三次握⼿和四次挥⼿过程: 1.1 三次握⼿ TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采⽤三次握⼿确认建⽴⼀个连接: TCP/IP协议中,TCP协议提供可靠的连接服务,采⽤三次握⼿建⽴⼀个连接,如图1所⽰。 图1 TCP三次握⼿建⽴连接 (1)第⼀次握⼿:建⽴连接时,客户端A发送SYN包(SYN=j)到服务器B,并进⼊
SYN_SEND状态,等待服务器B确认。 (2)第⼆次握⼿:服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时⾃⼰也发送⼀个SYN包(SYN=k),即SYN+ACK包,此时服务器B进⼊SYN_RECV状态。 (3)第三次握⼿:客户端A收到服务器B的SYN+ACK 包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进⼊ESTABLISHED状态,完成三次握⼿。 完成三次握⼿,客户端与服务器开始传送数据。 确认号:其数值等于发送⽅的发送序号 +1(即接收⽅期望接收的下⼀个序列号)。 TCP的包头结构:源端⼝ 16位⽬标端⼝ 16位序列号 32位回应序号 32位TCP头长度 4位reserved 6位控制代码 6位窗⼝⼤⼩ 16位偏移量 16位校验和 16位选项 32位(可选)这样我们得出了TCP包头的最⼩长度,为20字节 第⼀次握⼿:客户端发送⼀个TCP的SYN标志位置1的包指明客户打算连接的服务器的端⼝,以及初始序号X,保存在包头的序列号(Sequence Number)字段⾥。 第⼆次握⼿:服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,将确认
序号(Acknowledgement Number)设置为客户的I S N加1以.即X+1。第三次握⼿.客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1.并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对⽅.并且在数据段放写ISN的+1 下⾯是具体的例⼦截图:
1.此图包含两部分信息:TCP的三次握⼿(⽅框中的内容) (SYN, (SYN+ACK), ACK)
2. TCP的数据传输 ([TCP segment of a reassembled PUD])可以看出,server是将数据TCP层对消息包进⾏分⽚传输
(1)Server端收到HTTP请求如GET之后,构造响应消息,其中携带⽹页内容,在server端的HTTP层发送消息200 OK->server端的TCP
层;
(2)server端的TCP层对消息包进⾏分⽚传输;
中轴旋转门(3)client端的TCP层对接收到的各个消息包分⽚回送响应;
(4)client端的TCP层每次收到⼀部分都会⽤ACK确认,之后server继续传输,client继续确认,直到完成响应消息的所有分⽚之
后,Server发送组合HTTP响应包 200 OK,此时在client端的消息跟踪中才可以显⽰HTTP 200 OK的消息包
土壤保水剂
1.2 四次挥⼿,关闭连接
由于TCP连接是全双⼯的,因此每个⽅向都必须单独进⾏关闭。这个原则是当⼀⽅完成它的数据发送任务后就能发送⼀个FIN来终⽌这个⽅向的连接。收到⼀个 FIN只意味着这⼀⽅向上没有数据流动,⼀个TCP连接在收到⼀个FIN后仍能发送数据。⾸先进⾏关闭的⼀⽅将执⾏主动关闭,⽽另⼀⽅执⾏被动关闭。内孔撑圆涨紧夹具
CP的连接的拆除需要发送四个包,因此称为四次挥⼿(four-way handshake)。客户端或服务器均可主动发起挥⼿动作,在socket编程中,任何⼀⽅执⾏close()操作即可产⽣挥⼿操作。
曲柄销
(1)客户端A发送⼀个FIN,⽤来关闭客户A到服务器B的数据传送。
(2)服务器B收到这个FIN,它发回⼀个ACK,确认序号为收到的序号加1。和SYN⼀样,⼀个FIN将占⽤⼀个序号。
(3)服务器B关闭与客户端A的连接,发送⼀个FIN给客户端A。
(4)客户端A发回ACK报⽂确认,并将确认序号设置为收到序号加1。
TCP采⽤四次挥⼿关闭连接如图2所⽰。
图2 TCP四次挥⼿关闭连接
参见wireshark抓包,实测的抓包结果并没有严格按挥⼿时序。我估计是时间间隔太短造成。
2、深⼊理解TCP
扫读笔
连接的释放: 由于TCP连接是全双⼯的,因此每个⽅向都必须单独进⾏关闭。这原则是当⼀⽅完成它的数据发送任务后就能发送⼀个FIN来终⽌这个⽅向的连接。收到⼀个 FIN只意味着这⼀⽅向上没有数据流动,⼀个TCP连接在收到⼀个FIN后仍能发送数据。⾸先进⾏关闭的⼀⽅将执⾏主动关闭,⽽另⼀⽅执⾏被动关闭。TCP协议的连接是全双⼯连接,⼀个TCP连接存在双向的读写通道。 简单说来是 “先关读,后关写”,⼀共需要四个阶段。以客户机发起关闭连接为例:1.服务器读通道关闭2.客户机写通道关闭3.客户机读通道关闭4.服务器写通道关闭关闭⾏为是在发起⽅数据发送完毕之后,给对⽅发出⼀个FIN(finish)数据段。直到接收到对⽅发送的FIN,且对⽅收到了接收确认ACK之后,双⽅的数据通信完全结束,过程中每次接收都需要返回确认数据段ACK。详细过程: 第⼀阶段 客户机发送完数据之后,向服务器发送⼀个FIN数据段,序列号为i; 1.服务器收到FIN(i)后,返回确认段ACK,序列号为i+1,关闭服务器读通道; 2.客户机收到
ACK(i+1)后,关闭客户机写通道; (此时,客户机仍能通过读通道读取服务器的数据,服务器仍能通过写通道写数据) 第⼆阶段 服务器发送完数据之后,向客户机发送⼀个FIN数据段,序列号为j; 3.客
户机收到FIN(j)后,返回确认段ACK,序列号为j+1,关闭客户机读通道; 4.服务器收到ACK(j+1)后,关闭服务器写通道。这是标准的TCP关闭两个阶段,服务器和客户机都可以发起关闭,完全对称。FIN标识是通过发送最后⼀块数据时设置的,标准的例⼦中,服务器还在发送数据,所以要等到发送完的时候,设置FIN(此时可称为TCP连接处于半关闭状态,因为数据仍可从被动关闭⼀⽅向主动关闭⽅传送)。如果在服务器收到FIN(i)时,已经没有数据需要发送,可以在返回
ACK(i+1)的时候就设置FIN(j)标识,这样就相当于可以合并第⼆步和第三步。读《Linux⽹络编程》关闭TCP连接章节,作以下笔记:
3、TCP的TIME_WAIT和Close_Wait状态 ⾯试时看到应聘者简历中写精通⽹络,TCP编程,我常问⼀个问题,TCP建⽴连接需要⼏次握⼿?95%以上的应聘者都能答对是3次。问TCP断开连接需要⼏次握⼿,70%的应聘者能答对是4次通讯。再问
CLOSE_WAIT,TIME_WAIT是什么状态,怎么产⽣的,对服务有什么影响,如何消除?有⼀部分同学就回答不上来。不是我扣细节,⽽是在通讯为主的前端服务器上,必须有能⼒处理各种TCP状态。⽐如统计在本⼚的⼀台前端机上⾼峰时间TCP连接的情况,统计命令: Linux shell代码 netstat -n | awk ’/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’ 结果: 除了ESTABLISHED,可以看到连接数⽐较多的⼏个状态是:FIN_WAIT1, TIME_WAIT, CLOSE_WAIT, SYN_RECV和LAST_ACK;下⾯的⽂
章就这⼏个状态的产⽣条件、对系统的影响以及处理⽅式进⾏简单描述。 TCP状态 TCP状态如下图所⽰: 可能有点眼花缭乱?再看看这个时序图 4、三种TCP状态 4.1
SYN_RECV 服务端收到建⽴连接的SYN没有收到ACK包的时候处在SYN_RECV状态。有两个相关系统配置:
1,p_synack_retries :INTEGER 默认值是5 对于远端的连接请求SYN,内核会发送SYN + ACK数据报,以确认收到上⼀个SYN连接请求包。这是所谓的三次握⼿( threeway handshake)机制的第⼆个步骤。这⾥决定内核在放弃连接之前所送出的 SYN+ACK 数⽬。不应该⼤于255,默认值是5,对应于180秒左右时间。通常我们不对这个值进⾏修改,因为我们希望TCP连接不要因为偶尔的丢包⽽⽆法建⽴。 2,p_syncookies ⼀般服务器都会设置p_syncookies=1来防⽌SYN Flood攻击。假设⼀个⽤户向服务器发送了SYN报⽂后突然死机或掉线,那么服务器在发出SYN+ACK应答报⽂后是⽆法收到客户端的ACK报⽂的(第三次握⼿⽆法完成),这种情况下服务器端⼀般会重试(再次发送SYN+ACK给客户端)并等待⼀段时间后丢弃这个未完成的连接,这段时间的长度我们称为SYN Timeout,⼀般来说这个时间是分钟的数量级(⼤约为30秒-2分钟)。 这些处在SYNC_RECV的TCP连接称为半连接,并存储在内核的半连接队列中,在内核收到对端发送的ack包时会查半连接队列,并将符合的requst_sock信息存储到完成三次握⼿的连接的队列中,然后删除此半连接。⼤量SYNC_RECV的TCP连接会导致半连接队列溢出,这样后续的连接建⽴请求会被内核直
接丢弃,这就是SYN Flood攻击。 能够有效防范SYN Flood攻击的⼿段之⼀,就是SYN Cookie。SYN Cookie原理由D. J. Bernstain和 Eric Schenk发明。SYN Cookie是对TCP服务器端的三次握⼿协议作⼀些修改,专门⽤来防范SYN Flood攻击的⼀种⼿段。它的原理是,在TCP服务器收到TCP SYN包并返回TCP SYN+ACK包时,不分配⼀个专门的数据区,⽽是根据这个SYN包计算出⼀个cookie值。在收到TCP ACK包
时,TCP服务器在根据那个cookie值检查这个TCP ACK包的合法性。如果合法,再分配专门的数据区进⾏处理未来的TCP连接。 观测服务上SYN_RECV连接个数为:7314,对于⼀个⾼并发连接的通讯服务器,这个数字⽐较正常。 4.2 CLOSE_WAIT 发起TCP连接关闭的⼀⽅称为client,被动关闭的⼀⽅称为server。被动关闭的server收到FIN后,但未发出ACK的TCP状态是CLOSE_WAIT。出现这种状况⼀般都是由于server端代码的问题,如果你的服务器上出现⼤量CLOSE_WAIT,应该要考虑检查代码。 4.3 TIME_WAIT 根据TCP协议定义的3次握⼿断开连接规定,发起socket主动关闭的⼀⽅ socket将进⼊TIME_WAIT状态。TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),在Windows下默认为4分钟,即240秒。TIME_WAIT状态下的socket不能被回收使⽤. 具体现象是对于⼀个处理⼤量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在⼤量的处于TIME_WAIT状态的socket, 甚⾄⽐处于Established状态下的socket多的多,严重影响服务器的处理能⼒,甚⾄耗尽可⽤的socket,停⽌服务。 5、 为什么需要TIME_WAIT? TIME_WAIT是TCP协议
⽤以保证被重新分配的socket不会受到之前残留的延迟重发报⽂影响的机制,是必要的逻辑保证。 和TIME_WAIT状态有关的系统参数有⼀般由3个,本⼚设置如下: p_tw_recycle = 1 p_tw_reuse = 1 p_fin_timeout = 30
p_fin_timeout,默认60s,减⼩fin_timeout,减少TIME_WAIT连接数量。 p_tw_reuse = 1表⽰开启重⽤。允许将TIME-WAIT sockets重新⽤于新的TCP连接,默认为0,表⽰关闭; p_tw_recycle = 1表⽰开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表⽰关闭。 为了⽅便描述,我给这个TCP连接的⼀端起名为Client,给另外⼀端起名为Server。上图描述的是Client主动关闭的过程,FTP协议中就这样的。如果要描述Server主动关闭的过程,只要交换描述过程中的Server和Client就可以
雨水管理系统了,HTTP协议就是这样的。 描述过程:Client调⽤close()函数,给Server发送FIN,请求关闭连接;Server收到FIN之后给Client返回确认ACK,同时关闭读通道(不清楚就去看⼀下shutdown和close的差别),也就是说现在不能再从这个连接上读取东西,现在read返回0。此时Server的TCP状态转化为CLOSE_WAIT状态。Client收到对⾃⼰的FIN确认后,关闭 写通道,不再向连接中写⼊任何数据。接下来Server调⽤close()来关闭连接,给Client发送FIN,Client收到后给Server回复ACK确认,同时Client关闭读通道,进⼊TIME_WAIT状态。Server接收到Client对⾃⼰的FIN的确认ACK,关闭写通道,TCP连接转化为CLOSED,也就是关闭连接。Client在TIME_WAIT状态下要等待最⼤数据段⽣存
期的两倍,然后才进⼊CLOSED状态,TCP协议关闭连接过程彻底结束。 以上就是TCP协议关闭连接的过程,现在说⼀下TIME_WAIT状态。从上⾯可以看到,主动发起关闭连接的操作的⼀⽅将达到TIME_WAIT状态,⽽且这个状态要保持Maximum Segment Lifetime的两倍时间。 原因有⼆:⼀、保证TCP协议的全双⼯连接能够可靠关闭⼆、保证这次连接的重复数据段从⽹络中消失
先说第⼀点,如果Client直接CLOSED了,那么由于IP协议的不可靠性或者是其它⽹络原因,导致Server没有收到Client最后回复的ACK。那么Server就会在超时之后继续发送FIN,此时由于Client已经CLOSED了,就不到与重发的FIN对应的连接,最后Server就会收到RST ⽽不是ACK,Server就会以为是连接错误把问题报告给⾼层。这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。所以,Client不是直接进⼊CLOSED,⽽是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对⽅收到ACK,最后正确的关闭连接。 再说第⼆点,如果Client直接CLOSED,然后⼜再向Server发起⼀个新连接,我们不能保证这个新连接与刚关闭的连接的端⼝号是不同的。也就是说有可能新连接和⽼连接的端⼝号是相同的。⼀般来说不会发⽣什么问题,但是还是有特殊情况出现:假设新连接和已经关闭的⽼连接端⼝号是⼀样的,如果前⼀次连接的某些数据仍然滞留在⽹络中,这些延迟数据在建⽴新连接之后才到达Server,由于新连接和⽼连接的端⼝号是⼀样的,⼜因为TCP协议判断不同连接的依据是socket pair,于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发⽣混淆了。所以TCP连接还要在TIME_WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从⽹络中消失。

本文发布于:2024-09-23 05:32:53,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/3/159133.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:连接   关闭   数据   服务器   发送   确认   状态
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议