网络连接状态

网络连接状态(11种)非常重要这里既包含三次握手中的也包括四次断开中的,所以要熟悉。

  • LISTEN 被动打开,首先服务器需要打开一个socket进行监听,监听来自远方TCP端口的连接请求,等于服务器端执行socket、bind、listen三个函数之后阻塞在accept处。
  • SYN_SENT 表示主动连接,客户端能通过应用程序调用connect()函数进行active open。于是客户端TCP发送一个SYN以请求建立一个连接,之后状态为SYN_SEND,表示已发送一个SYN到服务器端,等待SYN 1+ACK 0响应。
  • SYN_RECV 服务器端收到客户端的SYN 1,然后状态变为SYN_RECV。表示服务器收到了客户端发来的SYN,然后自己也响应了给客户端一个SYN 1+ACK 1,然后等待客户端确认。 这时候客户端过来的连接(属于半连接状态)被放在一个SYN队列里面,SYN泛洪***也是这样的,就是服务器响应了SYN+ACK之后,客户端就不在发送ACK了,然后继续发送SYN,直到把服务器的最大连接数量耗尽。 半连接队列长度是由内核参数tcp_max_syn_backlog来决定的。
  • ESTABLISHED 代表一个打开的连接,客户端收到服务器发送的SYN 1+ACK 1,就变为这个状态,然后向服务器发送ACK,如果服务器收到这个ACK,那么它也变为这个状态。这个状态就是表示连接以及建立,正在或即将传输数据。服务器收到ACK以后就会把半连接从上面提到的SYN队列中删除,然后放到ACCEPT队列中,这时这个半连接的状态就变成了ESTABLISHED。
  • FIN_WAIT1 主动关闭端(可以是服务器也可以是客户端)应用程序调用了close,于是其TCP发出FIN主动关闭请求,也就是四次断开的第一次,之后就进入了FIN_WAIT1状态,等待远程主机的ACK请求。
  • CLOSE_WAIT 被动关闭端(可以是服务器有可以是客户端)收到了对方发来的FIN后,进入该状态,然后发出ACK+1以回应FIN请求(它的接收也作为文件结束符传递给上层应用程序)。这个状态实际上是说客户端告诉服务器我没有请求或者数据要发送了,等待看看服务器或者说是进程还有没有数据要发送,如果有则继续发送,如果没有的话,就发送反向关闭指令。如果服务器大量连接是这个状态就要去查看程序,很有可能是程序设计的问题。
  • FIN_WAIT2 主动关闭端收到ACK+1后,就进入的FIN_WAIT2状态,也就等服务器是否还有数据发来,如果服务器没有数据了,那么服务器就发送的反向关闭指令。也就是反向关闭连接指令FIN1+ACK1。实际上是告诉客户端我的数据发送完了,可以关闭连接了。
  • LAST_ACK 被动关闭端,发送反向结束连接请求FIN 1+ACK 1,然后进入LAST_ACK状态,等待主动关闭端发送ACK。
  • TIME_WAIT 主动关闭端收到FIN 1 +ACK 1后,并进入TIME_WAIT状态,然后发送ACK+1,等待一段时间(2MSL)以确保服务器收到了ACK+1,然后自己进入CLOSED状态。这个阶段主要是客户端为了再次确认一下服务器是否可以关闭连接,因为网络毕竟是不可靠的。对于服务器有大量TIME_WAIT这个问题通常调整sysctl来解决。
  • CLOSING 比较少见,表示等待远程TCP对连接中断的确认。
  • CLOSED 被动关闭端在收到ACK包以后,就进入closed状态,连接结束。

四次断开过程

客户端:发送FIN给服务器表示主动请求断开连接,然后自己进入FIN_WAIT1阶段,等待服务器响应
服务器:收到客户端的FIN请求,发送ACK给客户端表示自己同意断开连接,服务器告诉上层【应用程序】有一个连接要请求断开并且进入CLOSE_WAIT阶段,等待应用程序做好关闭准备,其实就是把还没有传送完的数据传送完毕。
客户端:收到ACK以后进入FIN_WAIT2状态等待服务器发送FIN。
服务器:当应用程序做好关闭连接的准备后则发送FIN给客户端,并且服务器进入LAST_ACK阶段,等待客户端最后确认。
客户端:收到服务器的FIN以后发送ACK表示确认,此时客户端进入TIME_WAIT阶段,它并不是等什么确认而是等一段时间保证ACK可以有足够的时间被服务器收到,这个时间为1-4分钟。之后连接关闭。
服务器:收到客户端的ACK以后关闭连接。

关于MSL时长

任何TCP实现必须选择一个MSL值,有两种规范一种是一个MSL是2分钟,另外一种是30秒,所以这就意味着TIME_WAIT状态的持续时间为1-4分钟。MSL也是IP数据包在互联网上能存活的最长时间。另外我们追踪一个IP包的时候会有跳数概念,最大跳数255,所以即便到达最大跳数也不能超过一个MSL时间。

那为什么等2个MSL而不是1个或者3个呢?

IP数据包的最大存活时长是1个MSL,如果1个MSL内客户端发送的ACK丢了那么服务器肯定会重发最后一个FIN,而最后一个FIN这个数据包的最大存活时间也是1个MSL,所以客户端如果在2MSL时间内又收到服务器发来的FIN,就表示之前客户端发送的ACK确实丢了,这时候客户端会再次发送ACK。所以设置为1个太短,3个没必要。

关于TIME_WAIT的作用

  1. 客户端发送最后的ACK以后,如果服务器端收不到那么服务器会重发FIN,所以在1一个MSL时间内是为了确保客户端可以收到服务器重发的FIN(如果有必要)
  2. 如果在1MSL内服务器没有重发FIN,表示服务器已经收到客户端最后的ACK,那么也就表示双方都正常关闭了连接
  3. 在TIME_WATI阶段,主动关闭的一方不能重新建立一个和之前一样的连接,这是为了避免造成属于上一个连接的数据被归属到这次新连接,所以经过2MSL之后属于之前连接的数据包能到的也就到了不能到的也就被丢弃了,同时对于服务器来说它的应答数据也最多存活1MSL。

为什么上图的主动关闭是客户端

其实任何一方都可以主动关闭,只是我们在实际过程中双方通信肯定有一方作为客户端角色一方作为服务器角色存在,所以这里只是一个角色并不是说服务器不能主动关闭。在这里你需要牢记的是主动关闭和被动关闭的一方各自都会有什么状态。

TCP/IP 四次断开的更多相关文章

  1. tcp/ip四次挥手

    四次分手: 由于TCP连接是全双工的,因此每个方向都必须单独进行关闭.这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接.收到一个 FIN只意味着这一方向上没有数据流动,一个 ...

  2. TCP/IP三次挥手,四次断开(精简)

    很多协议都是基于TCP/IP协议的基础之上进行工作的,可能我们了解这些原理近期看来并无实际作用,因为它不像如一些web服务器配置一样,配置了我就可以使用,就可以提供服务. 但是从我们长远发展角度来看, ...

  3. TCP/IP 三次握手,四次断开

    TCP/IP 三次握手,四次断开 一.TCP报文格式                     TCP/IP协议的详细信息参看<TCP/IP协议详解>三卷 本. 下面是TCP报文格式图: 图 ...

  4. tcp/ip原理/三次握手/四次挥手

    @ tcp/ip原理 1.1 tcp/ip三次握手 1.1.1 建立过程说明 a)   由主机A发送建立TCP连接的请求报文, 其中报文中包含seq序列号, 是由发送端随机生成的, 并且还将报文中SY ...

  5. 理解TCP三次握手/四次断开的必要性

    1 TCP的三次握手与必要性 (1)三次握手图 (2)必要性:TCP通过三次握手建立可靠的(确保收到)的全双工通信. 1)第一次握手和第二次握手(ACK部分)建立了从客户端到服务器传送数据的可靠连接: ...

  6. TCP/IP协议(一)

    TCP/IP是Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协 ...

  7. TCP/IP握手协议

    转自:http://www.js123.net/t/n/n/2013/4/28/n_272.shtml 这篇介绍的也很棒:http://www.cnblogs.com/rootq/articles/1 ...

  8. TCP/IP笔记

    TCP/IP 连接 三次握手 TCP/IP 四次分手 @TODO TIME_WAIT 状态 有三种状态可以进入此状态 1.由FIN-WAIT-2,双方不同时发起FIN,主动关闭的一方在完成自身发起的关 ...

  9. TCP\IP三次握手连接,四次握手断开分析

    TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标 ...

随机推荐

  1. Java EE ----- Container/Injection

    容器(container)是一个类,实际上是component的子类,因此容器本身也是一个组件,具有组件的所有性质,但是它的主要功能是容纳其他组件和容器. 对于开发人员,需要引入复杂的代码解决事务以及 ...

  2. python 日常错误整理

    1.NameError: name 'raw_input' is not defined 问题原因:python 3 中raw_input已经被input 替代

  3. c# asp.net mvc4 使用uploadify插件实现上传功能

    [1]首先去官网下载插件:http://www.uploadify.com/download/ .ww我使用的是免费的,基于flash的版本.因为基于H5的版本需付费使用,然后使用该插件也就是做做毕设 ...

  4. VB输出数据到EXCEL

    Private Sub Command1_Click() Dim i As Long Dim j As Long , ) As Long Dim xlApp, WS, WB Set xlApp = C ...

  5. JS for循环 if判断、white循环。小练习二

    假设一个简单的ATM机的取款过程是这样的:首先提示用户输入密码(password),最多只能输入三次,超过3次则提示用户“密码错误,请取卡”结束交易.如果用户密码正确,再提示用户输入取款金额(amou ...

  6. 字符串转义为HTML

    有时候后台返回的数据中有字符串,并需要将字符串转化为HTML,下面封装了一个方法,如下 // html转义 function htmlspecialchars_decode(string, quote ...

  7. js函数柯里化,实现bind

    1.柯里化: 把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术. 举个栗子: 一个计算两数之和的函数,需要传递两个参数,柯里化 ...

  8. [LeetCode] Advantage Shuffle 优势洗牌

    Given two arrays A and B of equal size, the advantage of A with respect to B is the number of indice ...

  9. PyCharm下载及使用

    PyCharm教育版是一款能够对你编写Python程序的工作有所帮助的免费编译器. PyCharm-community下载链接:https://pan.baidu.com/s/1Hwd_TOVA3en ...

  10. 通过cmd命令,杀掉占用端口号的进程

    错误问题:[Error running public: Unable to open debugger port (127.0.0.1:53110): java.net.BindException & ...