LINUX小白学习之路-浅谈TCP三次握手四次挥手

浅谈TCP三次握手四次挥手

TCP协议是不同主机间会话最常用的传输层协议之一,TCP协议有以下特性
面向连接协议
全双工协议
半关闭
错误检查
将数据打包成段,排序
确认机制
数据恢复,重传
流量控制,滑动窗口
拥塞控制,慢启动和拥塞避免算法

TCP报文

在这里插入图片描述
1,源端口:客户端发起请求时的端口;目标端口:目标主机监听并相应的端口
2,序号:每个包传输都需要序号,范围:0-2^32-1
3,确认号:确认已经接收对方发送的包后让对方传的下一个包的序号,如接收对方包的序号为100,则发送的确认号为101,表示100序号的包已经接收成功,请发送101序号的包
4,数据偏移:与选项有关,用来确认距离TCP头部的长度,由于选项长度可变,所以以此字段指定TCP报文的总长度
5,保留,未使用
6,URG:紧急标志,与紧急指针关联,当URG=1表示需要先根据紧急指针处理紧急数据再处理正常数据
ACK:确认标记,表示对方发送的包已经收到
PSH:推送位,推送的数据先存在接收放的缓存buffer中,当PSH=1时,表示需要提前从buffer中接收此包
RST:重置连接标记,当出现主机间通信问题(崩溃等),此标记意味着需要重新建立连接
SYN:建立连接标记位,与三次握手(三包握手)相关
FIN:释放连接标记为,与四次挥手(四包挥手)相关
7,窗口,用来控制传输流量,因为每个主机间是要与不同的对象建立连接的,当网络带宽不足或内核繁忙时需要协商每次传输的包的数量(包的发送一次可能是多个,一次一次传效率不是很高)。如A主机一次发送5个包给B主机,B主机只能接收三个包,则B主机发送确认号为第四个包,此时窗口值就等于3.
8,检验和:用来校验TCP包数据是否完整
9,紧急指针:指向紧急数据,与URG标记位相关联
10,选项:常见选项:
最大报文段长度:Maxium Segment Size,MSS,通常1460字节
窗口扩大:Window Scale
时间戳: Timestamps
11,填充

TCP三次握手(三包握手)

在这里插入图片描述
1,客户端状态:关闭状态(CLOSED);服务器端状态:监听状态(LISTEN),时刻都要监听是否有请求发起
2,客户端:主动打开端口发送SYN=1,seq=x向服务器端发起建立连接的请求,此时客户端状态为:(SYN_SEND)
3,服务器端:在监听状态下接收到客户端发起的SYN建立请求,并接收seq为x的包,之后发送同意建立连接的标记SYN=1,ACK=1,seq=y,ack=x+1(SYN表示服务器端也向客户端发起建立连接的请求,ACK表示已经接收,seq表示服务器端发送的包的序号,ack表示客户端发送的x的包已经收到,请客户端发送第x+1序号的包),发送后此时服务器端的状态变为:SYN_RCVID,表示收到并回应。
4,客户端:接收服务器端的相应包,并发送ACK=1,seq=x+1,seq=y+1(ACK=1回应服务器端的建立连接的相应,正式确认连接,seq表示客户端发送的第x+1个包,ack表示服务器端下次发的包的序号y+1),此时客户端连接状态变为:建立连接状态(ESTABLISHED).
5,服务器端:接收客户端相应的ACK包,此时服务器端连接状态变为:建立连接状态(ESTABLISHED)正式确立连接完成。

问题:为什么两次连接不行,还要发送第三个回应包?
答:1,客户端发起SYN请求,服务器端做出回应,服务器端的SYN建立连接同样需要客户端做出回应
2.有可能网络等原因导致客户端发送了两个SYN请求,防止释放连接后服务器端又收到了SYN请求再次建立连接。
3.现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S 是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分 组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。(S表示服务器,C表示客户端)

TCP四次挥手(四包挥手)

在这里插入图片描述
客户端或者服务器端均可主动发次挥手请求,此处以客户端发起请求为例:
客户端与服务器端状态:建立连接状态(ESTABLISHED)
1,客户端:主动发起断开连接请求,发送FIN=1,seq=u(FIN为断开连接请求标记,seq表示发送此包的序号为u),此时客户端状态变为:FIN_CLOSE1(终止等待1)
2,服务器端:接收客户端发送的断开连接的请求包,并发送ACK=1,ack=u+1,seq=v(ACK表示已经接收,ack表示让客户端发送下个包序号为u+1,seq表示服务器端发送的包的序号),此时服务器端的状态变为:CLOSE-WAIT(等待断开连接中)
3,客户端:接收服务器端的ACK确认包,此时客户端状态变为:FIN_CLOSE2(终止等待2),还为接收到服务器的挥手请求,所以还是在等待阶段。
4,服务器端:等待一段时间后发送FIN=1,ACK=1,seq=w,ack=u+1(FIN发送断开连接请求,ACK表示再次对客户端发送断开请求包的回应,seq表示发送包的序号,ack表示让客户端发送下个包序号为u+1),此时服务器端需要等待客户端发送最后的断开连接的回应,此时服务器端状态为:LAST_ACK(最后确认状态)
5,客户端:客户端接收服务器端发送的FIN挥手请求,并发送ACK=1,seq=u+1,ack=w+1回应服务器端,此时客户端状态变为时间等待(TIME_WAIT)状态,并等待2MSL后完全切换至关闭状态(CLOSED)
6,服务器端:接收客户端发送的ACK相应包,将状态同样变为关闭状态(CLOSED),以此完成连接断开整个过程。

问题1:为什么客户端要等待2MSL时间才切换状态至结束?
答:可能网络等原因导致服务器端先发送FIN,后发送之前已经处理的包,客户端保持2倍MSL时间再断开保证数据能够完全接收。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。

问题2:为什么不能直接三次挥手,服务器端直接发送FIN请求端口连接,
答:这是因为可能服务器端的应用还有包要处理,所以需要等待应用将包处理结束才能发送挥手请求,而实际上是会出现三次挥手的(客户端发送FIN后,服务器端直接以FIN相应)

问题3:如果挥手阶段有一方发送断开请求后出现突发事件导致异常连接端口会有什么后果
答:主动发起端口的一方会主动结束,而未完全断开的一方由于没有收到完整的断开请求,一直在苦苦等待回应,此时服务器端半关闭状态就成了孤儿连接,由内核接管,等到规定的时间后,服务器主动消除连接。

部分参考:https://blog.csdn.net/qq_38950316/article/details/81087809

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值