Tcp连接的七次握手浅析
LINUX 查看tcp连接数及状态
# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 8947 等待足够的时间以确保远程TCP接收到连接中断请求的确认
FIN_WAIT1 15 等待远程TCP连接中断请求,或先前的连接中断请求的确认
FIN_WAIT2 1 从远程TCP等待连接中断请求
ESTABLISHED 55 代表一个打开的连接
SYN_RECV 21 再收到和发送一个连接请求后等待对方对连接请求的确认
CLOSING 2 没有任何连接状态
LAST_ACK 4 等待原来的发向远程TCP的连接中断请求的确认
TCP连接状态详解:
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: 没有任何连接状态
连接的三次握手

- 客户端向服务器发送SYN请求
- 服务器发送ACK回应请求,并同时发送一个SYN的请求给客户端
- 客户端回应ACK应答
关闭的四次握手
对于关闭流程,一共有三种情况:客户端主动关闭,服务器端主动关闭,客户端和服务器端同时主动关闭。这里仅仅以客户端主动关闭为例列出下图。

- 客户端主动关闭,发送FIN请求
- 服务器回应ACK应答
- 服务器被动关闭,发送FIN请求
- 客户端回应ACK应答
对于关闭流程,服务器端和客户端是对等的地位,其它两种场景处理过程类似。需要注意的是,由于对端是是可以主动关闭的,因此在代码中需要加上被动关闭的响应流程。
为什么连接和关闭握手次数不一样
看到上述流程,可能有一个疑问:为什么连接和关闭的握手次数不一样?其实,不论是连接还是关闭,客户端和服务器端都是发送了一次请求(SYN/FIN),回应了一次应答(ACK),它们是对称的。但是,在连接的时候服务器端的请求和应答是在一次握手中同时完成的,而关闭的时候却是分两次完成的,所以就造成了连接和关闭的握手次数不对称。
现在,新问题又来了:为什么连接时复用一次握手,而关闭的时候不复用握手?这个则是因为连接和关闭的行为不是一样所造成的。
- 在连接过程中,客户端是主动连接,服务器端是被动连接,这个顺序是确定了的,因此,可以复用第二次握手。
- 在关闭的过程中,客户端和服务器端可能同时主动关闭,此时就不能复用第二次握手了,因此请求和应答需要单独的发送。
Tcp连接的状态迁移图
前面只考虑了理想的情况,在实际的过程中,可能还需要处理一些异常操作,如下则是一个完成的TCP连接的状态迁移图。

半打开连接和半关闭连接
如前所述,建立或关闭一个连接时需要三或四步的,在这个过程中,TCP连接则会处于一个半打开或半关闭状态。例如,前面状态图中的FIN_WAIT_1和FIN_WAIT_2就是半关闭状态。
一般来说,半连接只是一个暂停的过程。但是,在一些异常的情况的时候(如远端主机故障)的时候常常会造成半关闭连接,由于Tcp连接处于半打开或半关闭状态的时候,仍然会占用相应的端口资源,尤其对于http之类的海量服务来说,会造成大量端口被占用,会造成资源的浪费。
另外,有的程序也针对Tcp协议的这一特征来恶意进行网络攻击。例如,对于一个服务器,大量的恶意客户端建立连接后,既不发请求,也不close套接字,这种情况下服务器如何保护自己呢。因为如果听之任之的话,大量的恶意连接会耗尽服务器的可用描述符,导致服务器不能服务。就算服务器主动close,如果客户端不close的话,那么这个连接还是不能完全释放。对于服务器来说,需要增加相应的机制进行半连接的处理。
Tcp连接的七次握手浅析的更多相关文章
- 为什么建立TCP连接需要三次握手,为什么断开TCP连接需要四次握手,TIME_WAIT状态的意义
为什么建立TCP连接需要三次握手? 原因:为了应对网络中存在的延迟的重复数组的问题 例子: 假设client发起连接的连接请求报文段在网络中没有丢失,而是在某个网络节点长时间滞留了,导致延迟到达ser ...
- TCP连接的3次握手和4次挥手
TCP连接的3次握手和4次挥手笔记 三次握手 TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确 ...
- 详解TCP连接的“三次握手”与“四次挥手”(上)
一.TCP connection 客户端与服务器之间数据的发送和返回的过程当中需要创建一个叫TCP connection的东西: 由于TCP不存在连接的概念,只存在请求和响应,请求和响应都是数据包,它 ...
- 详解TCP连接的“三次握手”与“四次挥手”(下)
上文链接: 详解TCP连接的"三次握手"与"四次挥手"(上) 四.TCP的四次挥手(Four-Way Wavehand) 0.前言 对于"三次握手&q ...
- tcp连接的三次握手
为什么tcp连接需要三次握手才能建立连接 主要是为了初始化sequence number的初始值,通信的双方要互相通知双方的sequence number,这个要作为以后数据通信的序号,保证以后不会因 ...
- TCP连接的三次握手和四次解散过程
客户端和服务器在使用TCP连接传输数据的过程中,需要经过三次握手建立连接和四次握手断开连接操作. 具体如下图所示 上图描述了TCP连接从建立到断开的详细过程,以下就其中的具体报文细节展开讨论. 在TC ...
- tcp连接的3次握手
http://www.tcpipguide.com/free/t_TCPConnectionEstablishmentProcessTheThreeWayHandsh-3.htm synchronou ...
- python网络编程--TCP连接的三次握手(三报文握手)与四次挥手
一.TCP连接 运输连接有三个阶段: 连接建立.数据传送和连接释放. 在TCP连接建立过程中要解决以下三个问题: 1,要使每一方能够确知对方的存在. 2.要允许双方协商一些参数(如最大窗口之,是否使用 ...
- 为什么TCP连接需要三次握手分开需要四次握手?
TCP的三次握手和四次断开TCP是一个面向连接的服务,面向连接的服务是电话系统服务模式的抽象,每一次完整的数据传输都必须经过建立连接,数据传输和终止连接3个过程,TCP建立连接的过程称为三次握手,下面 ...
随机推荐
- logging模块知识点及应用小结
Logging模块知识点: 一.分为5个级别:debug(),info(),warning(),error(),critical().级别由低到高 1.1最简单的用法: 1.2 如果想把日志写到文件 ...
- Jmeter(六)Jmeter脚本包含要素及书写习惯
Jmeter有丰富的组件,逻辑控制器.配置原件.Sampler.定时器.前置处理器.后置处理器.断言.监听器:而编写脚本一定要养成个人习惯,让人看到Jmeter的脚本目录结构树能够一目了然:因此,首先 ...
- Spring Boot安装及入门实现
在Eclipse里使用Spring boot,首先需要安装Spring boot的插件STS. 注意:STS插件3.7.0以上版本启动需要JDK1.8 打开Eclipse 菜单栏 Help -> ...
- scala语法在spark withScope上的应用
withSpout在spark中是用来做DAG可视化的,它在代码里的用法如下(以map为例,spark 2.0.0版本) def map[U: ClassTag](f: T => U): RDD ...
- boost 学习笔记 2: timer
boost 学习笔记 2: timer copy from:http://einverne.github.io/post/2015/12/boost-learning-note-2.html 1:ti ...
- cocos源码分析--用Sprite加载自定义着色器
本文写一个使用动态更新属性变量的自定义着色器.在这个例子中,小图标的位置根据手指的触摸而移动,以屏幕重点为参照物,屏幕中向下的部分根据手指的点击乘以一个绿色的颜色值,向上的部分乘以一个红色的颜色值. ...
- Java - 34 Java 文档注释
Java 文档注释 Java只是三种注释方式.前两种分别是// 和/* */,第三种被称作说明注释,它以/** 开始,以 */结束. 说明注释允许你在程序中嵌入关于程序的信息.你可以使用javadoc ...
- jQuery操作标签
jQuery操作标签 样式操作: 对标签的样式进行修改,那么操作样式的方法是什么? 样式类: addClass();// 添加指定的CSS类名. removeClass();// 移除指定的CSS类名 ...
- python中的sockeserver模块简单实用
1. socketserver模块简介 在python的socket编程中,实用socket模块的时候,是不能实现多个连接的,当然如果加入其它的模块是可以的,例如select模块,在这里见到的介绍下s ...
- 'pip' 不是内部或外部命令
安装好Python,在环境变量Path中加入相应路径信息后,Python命令没问题,但是运行pip失败: 'pip' 不是内部或外部命令,Pip工具已经自带安装好了,只是跟Python命令一样,需要我 ...