精华内容
下载资源
问答
  • 文章目录TCP三次握手,四次挥手TCP三次握手TCP四次挥手TCP三次握手的原因(为什么不是2次或者4次)TCP握手比挥手多一次的原因 TCP三次握手,四次挥手 TCP的报文段结构: 对于TCP的三次握手,需要用到的信号量以及...

    TCP三次握手,四次挥手

    TCP的报文段结构:

    对于TCP的三次握手,需要用到的信号量以及序列号有:

    • SYN:1位,其中SYN=1表示建立连接
    • seq:32位序号,随机生成
    • ACK:1位,其中ACK=1表示确认消息有效
    • ack:32位确认序号,seq+1
    • FIN:1位,其中FIN=1表示中断连接

    TCP三次握手

    TCP四次挥手

    TCP三次握手的原因(为什么不是2次或者4次)

    TCP协议

    • 需要建立连接才可以起作用

    • 需要Client端和Server端都具有正常的发送和接收能力

    握手Client端可以验证的能力Server端可以验证的能力
    第一次Client发送、Server接收
    第二次Server发送、Client发送、Server接收、Client接收
    第三次Client接收、Server发送

    所以只有三次挥手,Client端和Server端才可以验证双方都具有正常的发送和接收能力

    TCP挥手比握手多一次的原因

    当Client端发出FIN报文段时,只可以说明Client端没有数据发送了,但是Client端还可以从Server端接收数据。

    当Server端发送ACK报文段时,只可以说明它知道了Client端没有数据发送了,但是Server端还可以发送数据。

    当Server端发送FIN报文段时,表示Server端也没有数据发送了。

    当Client端接收到后会返回ACK,之后彼此就会愉快的中断这次TCP连接。

    展开全文
  • 在调试客户端和服务器端(使用TCP套接字)的代码时我发现,如果先结束服务器端后结束客户端,紧...为了找出这个问题的原因,我复习了TCP的十种状态以及四次挥手的详细过程,我的疑问得以解答同时这也解释了文章的题...

            在调试客户端和服务器端(使用TCP套接字)的代码时我发现,如果先结束服务器端后结束客户端,紧接着再重启服务器端就会出现绑定失败的错误 OSError: [Errno 98] Address already in use   等待一段时间后大概一分钟左右就能正常重启服务器端。为了找出这个问题的原因,我复习了TCP的十种状态以及四次挥手的详细过程,我的疑问得以解答同时这也解释了文章的题目,为什么在四次挥手的过程中一般是客户端先发起的。

                       TCP十种状态

            因为TCP是全双工的,所以客户端和服务端都可以先进行挥手。在socket编程中哪一方先执行close()操作,哪一方则先进行挥手(发送FIN包)。

            以客户端先挥手为例,在TCP处于TIME_WAIT状态时,客户端从TIME_WAIT状态到CLOSED状态需要2MSL,因为客户端要确定服务端收到了ACK,如果服务端没收到ACK,客户端则一定会在2MSL时间内再收到一次FIN。而在socket编程中客户端一般不需要绑定,而服务器端一般都要绑定,如果先结束服务器端则是服务器端先进行挥手操作,那么服务器端从TIME_WAIT到CLOSED状态则需要2MSL。这段时间服务器端绑定的端口号被占用了,套接字不会释放。所以这段时间重启了服务器之后,会出现绑定失败的错误OSError: [Errno 98] Address already in use。

    注解:MSL是什么?

           MSL 是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。RFC 793中规定了MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。

    要详细了解TCP的三次握手和四次挥手推荐这篇文章。https://www.cnblogs.com/Jessy/p/3535612.html

    展开全文
  • TCP挥手流程

    2018-05-26 12:57:05
    TCP挥手流程

    TCP握挥手流程

    这里写图片描述

    展开全文
  • 浅谈 TCP 四次挥手

    万次阅读 2018-02-07 14:42:42
    之前自己学习的网络都是浅尝辄止,最近被人反复问起 TCP 相关的挥手问题的相关问题,有必要整理下自身所学,以提供自己和别人查阅。 下图是 TCP 挥手的一个完整流程,这里引用了 tcpipguide 的流程图,更加直观的...

    之前自己学习的网络都是浅尝辄止,最近被人反复问起 TCP 相关的挥手问题的相关问题,有必要整理下自身所学,以提供自己和别人查阅。

    下图是 TCP 挥手的一个完整流程,这里引用了 tcpipguide 的流程图,更加直观的了解下挥手过程。

    undefined

    首先不要被这里的图给迷惑了,因为连接的主动断开是可以发生在客户端,也同样可以发生在服务端。

    FIN_WAIT1

    由图可知,当一方接受到来自应用断开连接的信号时候,就发送 FIN 数据报来进行主动断开,并且该连接进入 FIN_WAIT1 状态,连接处于半段开状态(可以接受、应答数据,当不能发送数据),并将连接的控制权托管给 Kernel,程序就不再进行处理。一般情况下,连接处理 FIN_WAIT1 的状态只是持续很短的一段时间。

    我这里通过对数据包的拦截(不对 FIN 请求进行应答)来实现 FIN_WAIT1 状态,下图是主动断开一遍的 FIN 数据发送抓包记录。

    undefined

    在 18:12.43 的时间点,这台机器主动断开连接,并发送 FIN 请求,并且达到 RTO 后未收到响应后,一共重试了9次,每次重试时间是上一次的2倍,这条连接额外占用了 54 秒的时间。如果在服务中,这类连接数据一多就会消耗大量的服务器资源,我这里简单的提供 2 个参数来处理这个问题。

    tcp_orphan_retries :Integer,这里系统参数默认为 9(文档里面默认值为7,和系统配置有关),就是近端丢弃 TCP 连接的时候,重试次数,在我的系统中。在刚刚那种情况,如果将该参数调整为 3 次,这类连接在系统中存活的时间就会大大减少,从而缓解这个问题。如果你的系统负载很大,有发现是因为 FIN_WAIT1 引起的,也可以适当的调整这个参数。

    tcp_max_orphans:Integer,默认值 8096。系统所能处理不属于任何进程的 TCP sockets 最大数量。当超过这个值所有不属于任何进程的 TCP 连接(孤儿连接)都会被重置。这个参数仅仅是为了防御简单的 Dos ,不能依赖这个参数。

    FIN_WAIT2

    当主动断开一端的 FIN 请求发送出去后,并且成功够接受到相应的 ACK 请求后,就进入了 FIN_WAIT2 状态。其实 FIN_WAIT1 和 FIN_WAIT2 状态都是在等待对方的 FIN 数据报。当 TCP 一直保持这个状态的时候,对方就有可能永远都不断开连接,导致该连接一直保持着。

    tcp_fin_timeout :Integer,默认 60,单位秒,不属于任何应用的孤儿连接保持 FIN_WAIT2 状态的最长时间,一当超过这个时间,就会被本地直接关闭,不会进入 TIME_WAIT 状态。
    但是总体上来将处于 FIN_WAIT2 状态的 TCP 连接,威胁要比 FIN_WAIT1 的小,占用的资源也很小,通常不会有什么问题。

    TIME_WAIT

    当前面的步骤都顺利完成了,并且接受到了 被动关闭端 发送过来的 FIN 数据报后,系统做出 ACK 应答后,该连接就进入了尾声,也就是 TIME_WAIT 状态。内核会设定一个时间长度为 2MSL 的定时器,当定时器在到时间点后,内核就会将该连接关闭。反之,当连接尚未关闭的时候,又收到了对方发送过来的 FIN 请求(可能是我们发送出去的请求对方并未收到),或者收到 ICMP 请求(比如 ACK 数据报,在网络传输中出现了错误),该连接就会重新发送 ACK 请求,并重置定时器。

    为什么要设置时间为 2MSL?

    MSLMaximum Segment Lifetime,译为“报文最大生存时间”,任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

    等待 2MSL 时间主要目的是怕最后一个 ACK 对方没收到,那么对方在超时后将重发第三次握手的 FIN ,主动关闭端接到重发的 FIN 包后,系统收到该分组后,可以再发一个 ACK 应答包。还有就是等来该连接在网络上的所有报文都传输完毕,所以处于 TIME_WAIT 状态时候,两端的端口都是不可用的,迟到的报文都会被废弃。

    如果我们设置的时间少于 2MSL ,旧的连接刚刚关闭,这个时候有同样五元组的新连接进来了,而之前的连接还有残留报文在网络上,就会干扰新的连接的使用。

    反之,如果连接处于 TIME_WAIT 过长,造成新 socket 无法复用这个端口,即使这个连接完全废弃(通常来说一个端口释放后会等待两分钟之后才能再被使用)。就像拉完屎还占着茅坑,可以尝试使用下SO_REUSEADDR(socket 参数),比如在服务停止后立即重启,这个时候可能会遇到原先的连接还处于 TIME_WAIT 状态,导致无法绑定原先的端口,就可以使用 SO_REUSEADDR。

    tcp_timestamps: Boolean,默认1,表示tcp通讯的时候是否是否使用时间戳。如下图,在 TCP 头部信息的扩展头部字段中就附带了时间戳,数据长度为两个4字节。TSval是该数据报发送出来的时间,TSecr是回显时间戳(即该ack对应的data或者该data对应的上次 ack 中的 TSval 值)

    undefined

    tcp_tw_reuse:Boolean,默认0,只在客户端有效,就是 TCP TIME_WAIT 链路复用。比如,当客户端不断向服务端建立连接获取数据,当每次都是客户端自己关闭连接,导致服务端进入 TIME_WAIT,之后客户端又要不断重连对方继续拉取数据,这个时候就可以复用 TIME_WAIT 的连接。当连接复用后势必会有旧连接残留在网络上的数据报,那么这些数据报要怎么处理,才能不影响新的连接的使用呢。可以使用上面的参数,时间戳来判断,建立建立后将缓存的时间戳更新到现在,当早于这个时间戳的数据报进来就表明是老连接的数据,内核会直接废弃掉。

    tcp_tw_recycle:Boolean,默认0,启动后能够更快地回收 TIME_WAIT 套接字。不再是2MSL,而是几个 RTO 内进行回收。所以在网络上同样会残存旧连接的数据报,内核同样可以通过时间戳的方式来判断、丢弃过时数据报。

    在早期的网络通信中,开启这个参数会导致一个问题。当多个客户端通过NAT方式联网同时与服务端通信,对于服务端只收到一个IP就好像是一台客户端进行与其进行通讯,但是客户端之间会有时间戳差异,就会导致服务端会将认为过期的数据报丢弃。导致只允许一个客户端与其进行通讯。现在的 NAT 服务器已经将协议升级成了NAPT,可以采用多端口与服务端通讯就可以避免这件事情。

    CLOSE_WAIT

    当被动关闭端,也就是图中的服务端,接受到了对方发送过来的 FIN 请求,并且对请求做出应答后,该连接就进入了 CLOSE_WAIT ,当连接处于这个状态的时候,该连接可能有数据需要发送,或者一些其他事情要做,当这类连接过多的时候,就会导致网络性能下降,耗尽连接数,无法建立新的连接。

    比如连接一直没得到释放,相应的资源一直被占用,一但达到句柄数的上限( linux 可以通过 ulimit -a 查看 open files 数值,默认1024 )后,新的请求就无法继续处理,就会返回大量的 Too Many Open Files 错误。

    常见错误原因

    1.代码层面上未对连接进行关闭,比如关闭代码未写在 finally 块关闭,如果程序中发生异常就会跳过关闭代码,自然未发出指令关闭,连接一直由程序托管,内核也无权处理,自然不会发出 FIN 请求,导致连接一直在 CLOSE_WAIT

    2.程序响应过慢,比如双方进行通讯,当客户端请求服务端迟迟得不到响应,就断开连接,重新发起请求,导致服务端一直忙于业务处理,没空去关闭连接。这种情况也会导致这个问题。

    缓解方案

    1.修改 /etc/security/limits.conf 配置文件中参数,提高句柄数上限
    2.修改 tcp 参数

    参数名默认值优化值说明
    net.ipv4.tcp_keepalive_time72001800单位秒,默认为7200s,就是说一个异常的CLOSE_WAIT连接至少会维持2个小时
    net.ipv4.tcp_keepalive_probes93在认定TCP连接失效之前,最多发送多少个keepalive探测消息。
    tcp_keepalive_intvl7515探测消息未获得响应时,重发该消息的间隔时间(秒)。

    3.检查自己的代码,修改连接不规范的地方。

    LAST_ACK

    当被动关闭一段,发送出去了 FIN 数据报后,套接字就进入了 LAST_ACK 状态,并且等待对方进行发送 ACK 数据报。

    1.收到了响应的ACK数据报后,连接进入CLOSED 状态,并释放相关资源
    2.如果超时未收到响应,就触发了TCP的重传机制。

    到此整个挥手流程就结束了。

    相关文档

    https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

    展开全文
  • 两张动图-彻底明白TCP的三次握手与四次挥手

    万次阅读 多人点赞 2017-06-04 21:53:54
    TCP连接的释放(四次挥手) 数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,然后客户端主动关闭,服务器被动关闭。 客户端进程发出连接释放报文,并且停止发送数据。...
  • TCP四次挥手原理

    千次阅读 2019-11-02 17:54:11
    TCP协议\TCP四次挥手
  • TCP 四次挥手

    2019-07-25 16:18:52
    TCP的三次握手和四次挥手通常同时被谈起,上篇文章我们说到了TCP的三次握手,那么四次挥手又是什么呢? 今天我们就聊聊什么是四次挥手。在说什么是四次挥手之前,我们还是要提出几个问题。 1.为什么要挥手那么...
  • TCP握手挥手的过程分析T
  • Tcp四次挥手

    2018-12-16 18:11:46
    四次挥手: 四次挥手用于关闭此次建立连接请求,确认调用了close 四次挥手之后才能释放资源
  • TCP IP 四次挥手流程

    2021-05-23 20:34:02
    TCP IP 四次挥手流程
  • TCP四次挥手

    2018-06-19 20:50:30
    1、什么是TCP四次挥手TCP链接在关闭时,会进行四次通信,此时客户端或者服务端都可以主动发起,这就是所谓的四次挥手,在这四次通信后,TCP链接就会正在断开,否则仅仅只是半链接而已。 2、TCP四次挥手流程...
  • TCP 四次挥手.pdf

    2021-09-14 14:14:31
    TCP 四次挥手.pdf
  • TCP握手挥手的过程分析.
  • TCP四次挥手详解

    千次阅读 2017-06-02 16:56:40
    TCP四次挥手1.前言 关于 TCP 三握手以及后面文章用到的东西可以查看我的这篇博文:三次握手 2.四次挥手 所谓四次挥手(Four-Way Wavehand)即终止 TCP 连接,就是指数据传送完毕需要断开一个 TCP 连接时,需要客户端...
  • 文章目录tcp的4次挥手 tcp的4次挥手
  • TCP握手与挥手

    2017-07-23 19:22:00
    TCP握手与挥手 (1)三次握手:  TCP 连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换 TCP 窗口大小(mss)信息。根据上面的图讲解通常情况下客户端计算机联系服务器...
  • tcp握手和挥手.pcap

    2019-11-15 09:45:16
    tcp格式的分析 tcp三次握手和四次挥手,客户端发送数据和服务器应答,服务器发送数据客户端应答。
  • tcp的连接时全双工的,因此每个方向都必须单独关闭。一方A发送完数据后,发送一个FIN请求断开与对方B的连接,B收到FIN表示不会再从A收到数据了,但是这个TCP连接中还是可以发送数据的,直到B发送完数据,也发送FIN,...
  • 趣谈TCP四次挥手

    千次阅读 2020-06-02 19:25:10
    TCP四次挥手断开连接1.先趣谈TCP四次挥手2.断开TCP连接:TCP四次挥手②为什么需要断开TCP连接?①为什么需要四次挥手断开TCP连接?分析四次挥手:断开连接 1.先趣谈TCP四次挥手 老样子,在开始正式的讲解TCP四次挥手...
  • TCP的三次握手与四次挥手理解及面试题(很全面)

    万次阅读 多人点赞 2018-07-17 20:56:17
    序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第...
  • tcp四次挥手

    千次阅读 2020-08-25 22:29:47
    4次挥手: 第一次挥手: Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。 第二次挥手: Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN...
  • TCP的四次挥手

    2018-08-12 23:20:48
    TCP连接的终止需要进行四次挥手才能完成,它的过程如下图 (这里假设终止有客户端发起,但是无论是客户端还是服务器都可以发起, 即下图中客户端和服务器的位置对调也是可以的): 第一次挥手 客户端发送FIN给...
  • TCP的释放,TCP的四次挥手
  • WireShark抓取TCP四次挥手报文实战

    万次阅读 2020-07-03 10:48:42
    TCP四次挥手 四次挥手的流程 挥手的过程可以由任何一方发起,这里以服务器端发起为例说明: 第一次挥手:服务器端发出FIN,用来断开服务器端到客户端的数据传送,进入FIN-WAIT-1状态 第二次挥手:客户端收到服务器...
  • Tcp四次挥手.png

    2020-07-19 11:28:19
    1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。  2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个...
  • Wireshark协议分析之TCP的三次握手和四次挥手,内含两个数据包,一个是三次握手,一个是四次挥手
  • TCP握手和挥手

    2019-02-28 15:45:00
    TCP三次握手 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。TCP三次握手大概流程: 第一次握手:建立连接时,客户端发送SYN包(syn = j)到服务器,并进入SYN_SEND状态,等待服务器...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 56,539
精华内容 22,615
关键字:

tcp挥手