3次握手
第一次握手:客户端主机A发送标志位位码SYN=1,随机产生seq number=x的数据包到服务器,客户端进入SYN_SEND
状态,等待服务器的确认;服务端主机B由SYN=1知道客户端主机A要求建立联机;
第二次握手:服务端主机B收到请求后要确认联机信息,向A发送ack number(主机A的seq+1),标志位位码SYN=1,标志位位码ACK=1,随机产生seq=y的包,此时服务器进入SYN_RECV
状态;
第三次握手:客户端主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及标志位位码ACK是否为1,若正确,主机A会再发送ack number(主机B的seq+1),标志位位码ACK=1,服务端主机B收到后确认seq值与标志位位码ACK=1则连接建立成功。客户端和服务器端都进入ESTABLISHED
状态,完成TCP三次握手。
TCP标志位位码,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) Reset(reset重置) URG(urgent紧急)
1. 为什么建立连接
tcp是一个可靠的传输机制,可靠在于每次收到一个数据都会相应的收到一个确认包之后才会将缓冲区的内容给删除掉,否则过一段时间就会重传。
建立连接就像是侦察兵侦查道路一样,我先看看这条路能不能走,如果能走,后面的大部队就跟上来了,如果不能走,后面的大部队就等着我继续侦查。
2. 为什么要用标志位SYN?
案例一: 没有标志位SYN的对话
客户端:嗨,服务器
服务器:你恐怕是傻子吧,给我发这个干嘛呢!!
案例二: 有标志位SYN的对话
客户端:嗨,服务器,我们开始连接吧
服务端:好的,可以
SYN: 告诉服务端发送这条数据的客户端想通过三次握手建立tcp连接
3. 为什么要用seq number,ack number
案例:
客户端:嗨,服务器,这是我要跟你连接的第一条数据。 seq number=1,SYN=1
服务器:一看序列号seq number是1,SYN是1,是想和我连接的,因此给他回复:好的,我已经收到你的数据了,我们可以连接了。 seq number=10,ack number=2此时的ack number是收到数据的seq number加上1
客户端:一看ack number是2,就是我上一条数据的seq number序列号加1,看来服务端已经同意我要连接了,因此回复:大哥,那我们开始发送数据吧。 seq number=2 ,ack number=11,此时三次握手建立成功
seq number:用来表示当前数据包的标号
ack number: 它的值是收到数据的seq number值加上一,用来告诉对方我收到了你的数据包。
4. 状态机是什么意思?
(1)我们会看到在图的左右两边有syn_send,syn_listen等字样,这个指的是在客户端或者服务端收到某条信息之后会进入到哪个状态中。这个状态就是tcp的状态机。
(2)为什么要有这个状态机,因此tcp的连接或者断开都是有一个明显的过程中,对于每个过程都表示一个状态对于以后的排查问题是很重要的,例如:当前有大量的tcp状态是处于syn_rvcd,这很明显是有问题的。
5. 为什么要用三次握手去建立连接,一次不行吗?
之前已经说过,tcp的可靠机制是由于会发送确认包,因此在建立连接的时候我必须要确认我发送的信息你是否收到了,如果没有收到,我是会继续发送的。
案例:
客户端:嗨,大哥,我们连接吧?(如果就这样就完了,那我客户端怎么知道我这条连接的数据到底发送成功没有呢?因此服务器必须给我回复信息,也就是第二次连接了)
服务器: 行,我们连接吧!(如果这样就完了,那么服务器就会想了,这条数据客户端到底收到了没有,没有收到咋办,真让人头疼,因此大哥跟你小弟说话了,不管怎样,你的表个态,这就有了第三次连接了)
客户单:好嘞,大哥,小弟知道了,我们开始发送数据吧。 (至此真正的连接才算完成)
注意:
连接都是从客户端开始的。
1. 没有客户端连接的时候
服务端:服务端首先处于syn_listen状态,也就是在监听客户端的连接。
客户端:客户端在没有收到服务器给我回复的确认包之前一直都处于syn_client状态。
2. 客户端发送:seq number=1,SYN=1的报文之后
服务端:服务端一旦接收到SYN=1的报文之后,状态就会变成syn_rcvd
3. 服务端发送:seq number=10,ack number=2的报文之后
客户端:客户端进入established的状态,并且会发送一个确认报文,当服务端接收到报文之后也会变成established状态。
4次挥手
(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
1. 为什么是服务端先发起的断开连接请求?
对于客户端而言,我们一般是向服务器索求数据的,因此当服务器端把我们所需要的数据完全的发送给客户端之后,为了提升工作效率,就会迫不及待的关掉连接,然后去做处理其他的请求。因此一般我们看到的都是服务器端先发送一个fin标志位为1的数据包表示服务器端想断开连接。
2. 标志位FIN
和三次握手的SYN一样,此处的FIN就是为了告诉对方我想断开连接
3. 为什么要用四次挥手去断开连接?
因为在tcp建立连接之后数据的交互是双向的,因此tcp连接也给我们虚拟出了两个通道,一个是server--->client的通道,一个是client--->server的通道
当我们的服务器数据传输完成之后server--->client的通道已经没有存在的必要的了,因此server发送fin断掉此通道的连接,但是此时的client--->server还要给server端发送ack确认报文,因此此时这个client-->server的通道还不能断开
当服务器收到了ack报文之后,也就代表着client--->server的的通道已经没有必要在存在了,因此客户端向服务端发送断开请求,服务端发送一个ack确认断开之后就可以断开了。
4. 当出现了大量的TIME_WAIT状态代表的是出现了高并发的请求。
WireShark 抓包工具分析tcp
Packet Details Pane(数据包详细信息), 在数据包列表中选择指定数据包,在数据包详细信息中会显示数据包的所有详细信息内容。数据包详细信息面板是最重要的,用来查看协议中的每一个字段。各行信息分别为
(1)Frame: 物理层的数据帧概况
(2)Ethernet II: 数据链路层以太网帧头部信息
(3)Internet Protocol Version 4: 互联网层IP包头部信息
(4)Transmission Control Protocol: 传输层T的数据段头部信息,此处是TCP
(5)Hypertext Transfer Protocol: 应用层的信息,此处是HTTP协议
TCP包的具体内容
从下图可以看到wireshark捕获到的TCP包中的每个字段
Wireshark过滤器设置
(1)抓包过滤器
捕获过滤器的菜单栏路径为Capture --> Capture Filters。用于在抓取数据包前设置。
ip host 60.207.246.216 and icmp表示只捕获主机IP为60.207.246.216的ICMP数据包。
Wireshark抓包分析TCP三次握手
(1)TCP三次握手连接建立过程
Step1:客户端发送一个SYN=1标志的数据包给服务端,请求进行连接,这是第一次握手;
Step2:服务端收到请求并且允许连接的话,就会发送一个SYN=1,ACK=1标志的数据包给发送端,告诉它,可以通讯了,并且让客户端发送一个确认数据包,这是第二次握手;
Step3:服务端发送一个ACK=1的数据包给客户端端,告诉它连接已被确认,这就是第三次握手。TCP连接建立,开始通讯。
(2)wireshark抓包获取访问指定服务端数据包
Step1:启动wireshark抓包,打开浏览器输入www.huawei.com。
Step2:使用ping www.huawei.com获取IP。
Step3:输入过滤条件获取待分析数据包列表 ip.addr == 211.162.2.183
图中可以看到wireshark截获到了三次握手的三个数据包。第四个包才是HTTP的, 这说明HTTP的确是使用TCP建立连接的。
第一次握手数据包
客户端发送一个TCP,标志位为SYN,seq number为0, 代表客户端请求建立连接。 如下图。
数据包的关键属性如下:
SYN :标志位,表示请求建立连接
Seq = 0 :初始建立连接值为0,数据包的相对序列号从0开始,表示当前还没有发送数据
Ack =0:初始建立连接值为0,已经收到包的数量,表示当前没有接收到数据
第二次握手的数据包
服务器发回确认包, 标志位为 SYN,ACK. 将确认序号(Acknowledgement Number)设置为客户的I S N加1以.即0+1=1, 如下图
数据包的关键属性如下:
[SYN + ACK]: 标志位,同意建立连接,并回送SYN+ACK
Seq = 0 :初始建立值为0,表示当前还没有发送数据
Ack = 1:表示当前端成功接收的数据位数,虽然客户端没有发送任何有效数据,确认号还是被加1,因为包含SYN或FIN标志位。(并不会对有效数据的计数产生影响,因为含有SYN或FIN标志位的包并不携带有效数据)
第三次握手的数据包
客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1.并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方.并且在数据段放写ISN的+1, 如下图:
数据包的关键属性如下:
ACK :标志位,表示已经收到记录
Seq = 1 :表示当前已经发送1个数据
Ack = 1 : 表示当前端成功接收的数据位数,虽然服务端没有发送任何有效数据,确认号还是被加1,因为包含SYN或FIN标志位(并不会对有效数据的计数产生影响,因为含有SYN或FIN标志位的包并不携带有效数据)。
就这样通过了TCP三次握手,建立了连接。开始进行数据交互
下面针对数据交互过程的数据包进行一些说明:
数据包的关键属性说明
Seq: 1
Ack: 1: 说明现在共收到1字节数据
Seq: 1
Ack: 951: 说明现在服务端共收到951字节数据
在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG。如下
其中,对于我们日常的分析有用的就是前面的五个字段。它们的含义是:SYN表示建立连接,FIN表示关闭连接,ACK表示响应,PSH表示有DATA数据传输,RST表示连接重置。