从大学有网络课程起就知道有三次握手这回事,但对其中到底发生了什么一直懵懵懂懂,今天打算借助 Wireshark 这一著名的网络数据包分析软件重现一下握手过程。服务器
字段对应关系及释义:网络
在 Wireshark 中左边实线(图中21 - 2八、133 - 13四、427 - 428)连起来的一段能够视为为同一次会话内发生的各个阶段,不过图中的是简单顺利的一次会话过程,没有失败重传、分片传输等其余状况。tcp
另外:测试
文中7001为服务器所在端口号。spa
第21个网络包:客户端发送第一个网络包,在头部写入发送方、接收方端口号(用来找到目标套接字),设置客户端初始序号为0, SYN 控制位为1,等待服务器确认,因为此时客户端还未接收过网络包,因此 ACK 控制位为0。code
第22个网络包:服务器收到网络包,一样返回一个响应包,在TCP头部写入发送方、接收方端口号(此时对服务器来讲是发送方)、服务端初始序号0, SYN 控制位1,另外还要设置 ACK 控制位为1,表示已收到有效网络包;除此以外能够注意到 ACK号 也被置为1了,就是上文提到的 SYN 控制位占用的一个确认号。blog
第23个网络包:客户端收到网络包,发现 SYN 控制位为1,表示链接成功,同时发送一个 ACK 控制位设置为1的网络包给服务器,告知服务器刚才的响应包已收到,这里能够发现序号变为1,那是由于服务器返回的响应包中确认了客户端发送的 SYN 控制位为1,因此序号须要 +1;在服务器收到后三次握手就所有完成了,后面就能够开始收发数据了。ip
后面的[TCP Window Update]是用来窗口更新的,这里不作阐述。get
第25个网络包:客户端发起了一个 HTTP 页面请求,TCP详细信息以下:it
能够看到这个网络包已经不仅仅是控制信息的传输,开始包含数据,而且数据占用621字节,同时 Wireshark 已经机智在计算下一个客户端发送的包序号了, 621…...
而后服务器告知客户端已收到该请求,响应第26个网络包:
ACK号 = 前一次的 ACK号 + 本次收到的数据字节数 = 1 + 620 = 621;
序号保持不变,由于本次只是发送控制信息,并无发送数据。
Tips:在 WireShark 选中某个网络包,如上图No.26,结果No.25前面出现了一个对勾,能够看做是No.26对No.25的消息确认。
在第27个网络包中,服务器针对HTTP请求返回页面内容:
能够看到这个网络包的数据大小为4152字节,这以后理论上在客户端应该会返回一个 ACK号 为4153的确认包。
在第28个网络包中,序号就如前面 Wireshark 计算的等于621,ACK号的计算和第26个网络包类似,再也不赘述。
在结束最后一个网络包的传输后,再过一段时间(上图中大概5秒),如没有数据往来Web服务器就会关闭链接,至于为何要延时,大概是为了短期内若是有后续数据交换,能够减小从新建立套接字创建链接的开销吧。
服务器生成包含断连控制信息 FIN 的TCP头部发送给客户端。
客户端告知服务器已收到断连信号 FIN , 由于收到的 FIN 占用一个确认号,因此回复的 ACK号 = 4153 + 1 = 4154。
客户端在读取全部缓冲区的数据后,也会向服务器发送一个 FIN 为1的网络包。
服务器同理返回 ACK号 确认收到 FIN 控制信息。
这就是断连操做的四次握手。
测试数据下载连接,过滤规则 tcp.port == 7001
。
该文章首发于个人我的站点