TCP的三次握手以及TCP状态转换图详解

标签: tcp 握手 tcp | 发表时间:2014-02-15 00:48 | 作者:u012088779
出处:http://blog.csdn.net

今天来讨论一下TCP的三次握手以及TCP的状态转换图。首先发一个三次握手的流程图如下:

三向交握之封包連接模式
圖 2.4-3、三向交握之封包连接模式
A:封包发起
  当用戶端想要对服务器端发起连接时,就必須要送出一個要求连线的封包,此时用戶端必须随机取用一個大于1024 以上的端口來做为程序通信的通道。然后在 TCP 的表头当中,必须带有 SYN 的主动连线(SYN=1),並并且记下发送给服务器端的序列号(Sequence number = 10001) 。

B:封包接收与确认封包发送
当服务器端收到这个包,并且确定要接受这个包,就会开始制作一个同时带有SYN=1, ACK=1 的封包, 其中那个 acknowledge 的号码是要給 client 端确认用的,所以改数字会比(A 步驟)里面的 Sequence 号码多1 (ack = 10001+1 = 10002), 那我们服务器也必须要确认用戶端确实可以接收我们的包才行,所以也会发送出一个Sequence (seq=20001) 給用户端,并且开始等待客户端的回应

C:发送确认包
当用户端收到服务器端发送的 ACK 数字后 (10002) 就能够确认之前发送的包被接收了, 接下来就会同意与服务器端建立连接,就会再一次发送一个确认包 (ACK=1) 給服务器,亦即是 acknowledge = 20001+1 = 20002 。
D:取得最后的确认
若一切都顺利,在服务器端收到带有 ACK=1 且 ack=20002 序列号的包后,客户端和服务器端就建立连接了。   



下面我们再来介绍一下TCP的状态转换图,如下:

TCP状态转换图
注:主动、被动 与 服务器、客户端没有明确的对应关系。
这个图N多人都知道,它排除和定位网络或系统故障时大有帮助,但是怎样牢牢地将这张图刻在脑中呢?那么你就一定要对这张图的每一个状态,及转换的过程有深刻 的认识,不能只停留在一知半解之中。下面对这张图的11种状态详细解析一下,以便加强记忆!

CLOSED: 这个没什么好说的了,表示初始状态。
LISTEN: 这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,可以接受连接了。
SYN_RCVD: 这个状态表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本 上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。因此这种状态 时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。
SYN_SENT: 这个状态与SYN_RCVD遥想呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状 态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。
ESTABLISHED:这个容易理解了,表示连接已经建立了。
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状态还有时常常可以用netstat看到。
FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接。
TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带 FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。
CLOSING: 这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的 ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什 么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报 文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。
CLOSE_WAIT: 这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对 方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。
LAST_ACK: 这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。
最后有2个问题的回答,我自己分析后的结论(不一定保证100%正确)
1、 为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?
这 是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一 个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未 必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文 和FIN报文多数情况下都是分开发送的。
2、 为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?
这是因为: 虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到 ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于 LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的 ACK报文。

同时打开

两个应用程序同时执行主动打开的情况是可能的,虽然发生的可能性较低。每一端都发送一个SYN,并传递给对方,且每一端都使用对端所知的端口作为本地端口。例如:

主机a中一应用程序使用7777作为本地端口,并连接到主机b 8888端口做主动打开。

主机b中一应用程序使用8888作为本地端口,并连接到主机a 7777端口做主动打开。

tcp协议在遇到这种情况时,只会打开一条连接。这个连接的建立过程需要4次数据交换,而一个典型的连接建立只需要3次交换(即3次握手)但多数伯克利版的tcp/ip实现并不支持同时打开。

SYN_RCVD与SYN_SEND都是转换为ESTABLISHED的中间状态,目标是两端均转换到ESTABLISHED状态。

同时关闭

如果应用程序同时发送FIN,则在发送后会首先进入FIN_WAIT_1状态。在收到对端的FIN后,回复一个ACK,会进入CLOSING状态。在收到对端的ACK后,进入TIME_WAIT状态。这种情况称为同时关闭。

同 时关闭也需要有4次报文交换,与典型的关闭相同。


作者:u012088779 发表于2014-2-14 16:48:45 原文链接
阅读:109 评论:0 查看评论

相关 [tcp 握手 tcp] 推荐:

TCP的三次握手以及TCP状态转换图详解

- - CSDN博客系统运维推荐文章
今天来讨论一下TCP的三次握手以及TCP的状态转换图. 首先发一个三次握手的流程图如下:. 圖 2.4-3、三向交握之封包连接模式.   当用戶端想要对服务器端发起连接时,就必須要送出一個要求连线的封包,此时用戶端必须随机取用一個大于1024 以上的端口來做为程序通信的通道. 然后在 TCP 的表头当中,必须带有 SYN 的主动连线(SYN=1),並并且记下发送给服务器端的序列号(Sequence number = 10001).

TCP/IP三次握手和HTTP过程

- - 互联网 - ITeye博客
TCP/IP三次握手和HTTP过程.        原文地址:http://www.cnblogs.com/tiwlin/archive/2011/12/25/2301305.html. 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接. TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上.

tcp/ip调优

- Lucseeker - 在路上
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送syn包(syn=x)到服务器,并进入SYN_SEND状态,等待服务器确认;. 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;.

TCP三次握手四次挥手详解

- - CSDN博客互联网推荐文章
TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 1;建立连接时,客户端向服务器端发送一个SYN包,进入SYN_SEND状态,在该状态下,客户端等待服务器端的确认包. 2;服务器端收到客户端的SYN包后,首先向客户端确认自己已收到客户端的SYN包,同时也要发送自己的SYN包,即要向发送方发送ACK包+SYN包,然后进入SYN——RECEIVE状态.

TCP连接的三次握手--一次故障记录

- - CSDN博客系统运维推荐文章
大家都知道tcp和udp协议,tcp可靠的网络传输协议,udp效率高但是不会进行传输确认,只有投递. 那么三次握手就是为了保证tcp的可靠传输,下边是用wireshark抓取一次失败的http请求的结果:. 首先TCP的三次握手是建立连接. NO1,113.31的主机给112.65的主机发送了一个包含syn的包并且设置seq等于0,来请求建立连接.

转载:Wireshark基本介绍和学习TCP三次握手

- - 互联网 - ITeye博客
Wireshark基本介绍和学习TCP三次握手. 用 Fiddler 来调试HTTP,HTTPS. 这篇文章介绍另一个好用的抓包工具wireshark, 用来获取网络数据封包,包括http,TCP,UDP,等网络协议包. 记得大学的时候就学习过TCP的三次握手协议,那时候只是知道,虽然在书上看过很多TCP和UDP的资料,但是从来没有真正见过这些数据包, 老是感觉在云上飘一样,学得不踏实.

[原]结合wireshark分析TCP和三次握手原理

- - HelloWorld
一、wireshark介绍.          wireshark数据包分析实战(第二版)电子书: http://pan.baidu.com/s/1LCZV   提取密码:   fqcv.         Wireshark(前称Ethereal)是一个 网络封包分析 软件. 网络封包分析 软件的功能是撷取 网络封包,并尽可能显示出最为详细的网络封包资料.

TCP 三次握手原理,你真的理解吗?

- -
阿里妹导读:最近,阿里中间件小哥哥蛰剑碰到一个问题——client端连接服务器总是抛异常. 在反复定位分析、并查阅各种资料文章搞懂后,他发现没有文章把这两个队列以及怎么观察他们的指标说清楚. 因此,蛰剑写下这篇文章,希望借此能把这个问题说清楚. 场景:JAVA的client和server,使用socket通信.

浅谈TCP优化

- - 火丁笔记
很多人常常对 TCP优化有一种雾里看花的感觉,实际上只要理解了TCP的运行方式就能掀开它的神秘面纱. Ilya Grigorik 在「 High Performance Browser Networking」中做了很多细致的描述,让人读起来醍醐灌顶,我大概总结了一下,以期更加通俗易懂. 传输数据的时候,如果发送方传输的数据量超过了接收方的处理能力,那么接收方会出现丢包.

TCP报文结构

- - 互联网 - ITeye博客
一、TCP报文结构如下:.  固定首部长度为20字节,可变部分0~40字节,各字段解释:. source port number:源端口,16bits,范围0~65525. target port number:目的端口,16bits,范围同上. sequence number:数据序号,32bits,TCP 连接中传送的数据流中的每一个字节都编上一个序号.