TCP三次握手四次分手

news/2024/5/17 18:20:31 标签: TCP

TCP建立连接时,为什么要进行三次挥手?
每一次TCP连接都需要三个阶段:建立连接,数据传送和连接释放。三次握发生在建立连接阶段。在谢希仁著《计算机网络》第四版中讲三次握手的目的是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。在另一部经典的《计算机网络》一书中讲三次握手的目的是为了解决网络中存在延迟的重复分组的问题。这两种不同的表述其实阐明的是同一个问题。
谢希仁版《计算机网络》中的例子是这样的,已失效的连接请求报文段的产生在这样一种情况下:A发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留了,以致延误到连接释放以后的某个时间才到达B。本来这是一个早已失效的报文段。但B收到此失效的连接请求报文段后,就误认为是A又发出一次新的连接请求。于是就向A发送确认报文段,同意建立连接。假定不采用三次握手,那么只要B发出确认,新的连接就建立了。由于现在A并没有发出建立连接的请求,因此不会理睬B的确认,也不会向B发送数据。但B却以为新的运输连接已经建立了,并且一直等待A发来数据。B的许多资源就这样白白浪费了。采用三次握手的办法可以防止上述现象的发生。例如在刚才的情况下,A不会向B的请求发出确认。B由于收不到确认,就知道A并没有要求建立连接。
这个例子很清晰的阐述了三次握手对建立可靠连接的意义。关于三次握手,这个问题的本质是,信道不可靠,但是通信双方需要就某个问题达成一致,而要解决这个问题,无论你在消息中包含什么信息,三次通信是理论上的最小值。所以三次握手不是TCP本身的要求,而是为了满足“在不可靠信道上可靠的传输信息“这一需求所导致的。请注意这里的本质需求,信道不可靠,数据传输要可靠。三次达到了,那后面你想接着握手也好,发数据也好,跟进行可靠消息传输的需求就没有关系了,因此,如果信道是可靠的,即无论什么时候发出消息,对方一定能收到,或者你不关心是否要保证对方收到你的消息,那就能像UDP那样直接发送消息就可以了,这可视为对三次握手目的的另一种解答思路。

举个打电话的例子:
A:你好,我是A,你能听到我说话吗?
B:听到了,我是B,你听到我在说话吗?
A:恩,听到了
连接建立,开始聊天!

这里写图片描述

首先由Client发出请求连接即SYN=1 ACK=0,TCP协议规定SYN=1时不能携带数据,但要消耗一个序号,因此声明自己的序号是seq=x,进入SYN_SEND状态,等待服务器确认;
然后Server进行回复确认,即SYN=1 ACK=1 seq=y,ack=x+1,此时服务器进入SYN_RECV状态;
再然后Client再进行一次确认,但不用SYN了,这时ACK=1,seq=x+1,ack=y+1,连接建立成功。客户端和服务器进入ESTABLISHED状态。
完成三次握手,客户端与服务器开始传送数据。

SYN:再连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同一建立连接,则应在响应报文中使SYN=1和ACK=1,因此,SYN置1就表示这是一个请求连接或连接接收报文。
ACK:TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1
seq:(sequence number)顺序号码
ack:(acknowledge number)确认号码

大写ACK是一种TCP协议规定的标识,小写ack是acknowledge number,为确认号码,值是seq+1。

SYN攻击:
在三次握手过程中,Server发送SYN-ACK之后,收到Clitent的ACK之前的TCP连接称为半连接,此时Server处于SYN_RECV状态,当受到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将占用为连接队列,导致正常的SYN请求因为队列满而被丢弃,因而引起网络堵塞甚至系统瘫痪。SYN攻击是一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定是SYN攻击了,使用如下命令可以让之现行: #netstat -nap | grep SYN_RECV

当客户端和服务端通过三次握手建立了TCP连接以后,当数据传送完毕,肯定是要断开TCP连接的阿。那对于TCP的断开连接,这里就有了神秘的“四次挥手“。
这里写图片描述
第一次挥手:主机1(可以是客户端也可以是服务器端),设置Sequence Number和Acknowledgment Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;
第二次挥手:主机2收到了主机1发送的FIN报文段,向主机1返回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意“你的关闭请求;
第三次挥手:主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态;
第四次挥手:主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明主机2已正常关闭,那好,主机1也可以关闭连接了。

为什么要四次分手呢?
TCP是一种面向连接的,可靠的,基于字节流的传输层通信协议。TCP时全双工模式,这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,他的数据已经全部发送完毕了;但是,这个时候主机1号是可以接收来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。
FIN_WAIT_1:其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是等待对方的FIN报文。而这两种状态的区别时:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报文是,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还是常常可以看到的。(主动方)
FIN_WAIT_2:上面已经详细的解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外一方却说,我暂时还有点数据需要传送给你(ACK)信息,稍后再关闭连接(主动方)
CLOSE_WAIT:这种状态的含义起始是表示在等待关闭。当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问的会回应一个ACK报文给对方,此时你进入CLOSE_WAIT状态。接下来,实际上你真正需要考虑的事情是查看你是否还有数据没有接受完或者是是否还有数据要发送给对方,如果没有的话,那么你就可以去close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接(被动方)。
LAST_ACK:它是被动关闭一方在发送完FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。(被动方)
TIME_WAIT:表示收到了对方的FIN报文,并发出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态(主动方)
CLOSED:表示连接中断。

为什么A等待2MSL,从TIME_WAIT到CLOSE?
第一,为了保证A发送的最后一个ACK报文段能够到达B。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到A以发送的FIN+ACK确认报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段。接着A重传一次确认,重新启动2MSL计时器。最后,A和B都正常进入到CLOSED状态。如果A在TIME-WAIT状态不等待一段时间,而是在发送完ACK报文段后立即释放连接,那么就无法收到B重传的FIN+ACK报文段,因此也不会再发送一次确认报文段。这样,B就无法按照正常步骤进入CLOSED状态。
第二,防止上一节提到的“已失效的连接请求报文段“出现在本连接中。A在发送完最后一个ACK报文段后,再经过时间2MSL,就可以使本连接持续时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。

参考博客:https://www.imooc.com/article/details/id/20812
http://uule.iteye.com/blog/2213562


http://www.niftyadmin.cn/n/874044.html

相关文章

HTTP状态码大全及重点提点

HTTP状态码 HTTP状态码是用来表示网页服务器HTTP响应状态的3位数字代码。由RFC 2616规范定义。 1xx – 信息性状态码(Informational) 100 - Continue 初始的请求已经接受,客户应当继续发送请求的其余部分。101 -Switching Protocols 服务器…

linux进程管理及工具的讲解

首言 计算机实际上可以做的事情实质上非常简单,比如计算两个数的和,再比如在内存中寻找某个地址等等。这些最基础的计算机动作被称为指令。所谓的程序,就是这样一系列指令所构成的集合。通过程序,我们可以让计算机完成复杂的操作…

Linux的作业控制

作业:jobs,在命令行运行或者是通过系统启动时运行的一个程序,但要注意的是,运行一个脚本的时候,可能会启动多个进程,所以作业和进程不是一一对应的。作业包括一个或多个进程,它主要是完成一系列…

Linux任务计划,周期性任务执行

概述:什么是计划任务呢?就像我们每个人日常生活中都会使用到的闹钟一样,按时的去提醒该干什么事,以免忘记。同样,我们在工作中也要每天在特定的时间内安排一些事情,这就是计划任务。 未来的某时间点执行以…

Centos开机过程

CentOS的启动流程总体顺序如下(以CentOS6为例): POST –> Boot Sequence –> bootloader(MBR) –> kernel –> 加载rootfs –> switchroot –> /sbin/init –> (配置文件:/etc/inittab,/etc/ini…

shell编程基本知识点

1 shell关键字 常用到的: 1 echo:打印文字到屏幕 2 ecex:执行另一个shell脚本 3 read:读标准输入 4 expr:对整数型变量进行算术运算 5 test:用于测试变量是否相等,是否为空,文件类型…

linux报告生成器之awk

awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。 模式 /正则表达式/:使用通配符的扩展集。关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试模式匹配表达式&…

iptable规则的设定与查看

Firewall:防火墙,隔离工具;工作于主机或网络的边缘,对于进出本地或网络的报文根据实现定义好的检查规则做匹配检查,对于能够被规则所匹配到的报文作出相应处理的组件; iptables/netfilter 功能 filter&a…