TCP三次握手 & WireShark实践分析 & 持续学习更新

一.什么是TCP?

定义:是一种面向连接的、可靠的、基于字节流的传输层通信协议
面向连接:为应用层实体提供端到端的通信功能
可靠的:确保数据包的顺序传送和数据的完整性。
字节流:数据传输方式。
TCP在OSI模型中位于传输层

二.TCP文章学习总结

注:二中部分内容或图摘自《你管这破玩意儿 TCP》(作者:无聊的闪客)中,做学习记录。
根据《你管这破玩意叫网络》(作者:无聊的闪客)所学可知,两台主机只要知道IP,并且网络是通的,就可以发送数据包给对方。这就是OSI七层模型中的物理层、数据链路层、网络层三层结构奠定的基础。在这基础上,你就可以随心所欲发送数据,于是有了第四层——传输层。

问题1:前三层协议只能把数据包从一个主机搬到另外一台主机,但是,到了目的地以后,数据包具体交给哪个程序(进程)呢?

解决方案:添加端口号,将原本主机到主机的通信,升级为了进程和进程之间的通信。(加入端口号后,其实就实现UDP了,不连接,不可靠,直接发送数据包)
在这里插入图片描述

问题2:丢包问题

解决方案:A 每发一个包,都必须收到来自 B 的确认(ACK),再发下一个,否则在一定时间内没有收到确认,就重传这个包。(称为【停止等待协议】使通信过程实现可靠交付)

问题3:网络不确定性,数据传输过程中,会经过各种路由,不一定所有数据包都走一条路。数据包顺序问题怎么解决?

解决方案:A在发送数据包中增加一个序号(seq),同时 B 要在 ACK 包上增加一个确认号(ack)。接收方的ack 的号是收到的最后一个数据包的序号 seq + 1,也就是告诉对方下一个应该发的序号是多少。这种方式叫累计确认或累计应答。

此问题扩展点:
1.TCP协议数据报文格式图

在这里插入图片描述

2.ACK和ack不是一个东西!
ACK (Acknowledgment):
  是TCP协议数据报文格式图中6个标志位之一,向对方确认它已成功接收。
  当 ACK=1 时,确认号字段(即ack)才有效。
ack (Acknowledgment Number):
  确认号:期望对方下一次传过来的TCP数据部分的第一个字节的编号。
3.TCP六个标志位
TCP标志位:
紧急 URG(Urgent):为1表示高优先级数据包
确认 ACK(Acknowledgment ):为1表示确认号字段有效
推送 PSH(Push):为1表示接收方尽快将这个报文交给应用层而不用等待缓冲区装满
复位 RST(Reset):为1表示出现严重错误,需要重新建立连接
复位 SYN:建立连接时同步序号;SYN=1ACK=0表示连接的请求,SYN=1ACK=1表示接收连接的请求
终止 FIN:为1表示传输完成,请求释放链接

问题4:A发送数据太多,B接收有限,接收不过来怎么办?

解决方案:数据包中加入win/window滑动窗口字段,表示自己的数据接收能力。该字段值是动态的。

问题5:网络拥塞时怎么办?

A 单方面通过试探,不断感知网络环境的好坏,进而确定自己的拥塞窗口的大小。

问题4和问题5的关联:

假如拥塞窗口的大小为 cwnd,上一部分流量控制的滑动窗口的大小为 rwnd,那么窗口的右边界受这两个值共同的影响,需要取它俩的最小值。
窗口大小 = min(cwnd, rwnd)

三.三次握手的过程

TCP的三次握手过程图
在这里插入图片描述

(TCP的三次握手过程图)
A:我准备好了(SYN=1),A状态修改为SYN-SENT(连接已发送)
B:我知道了(ACK=1),我也准备好了(SYN=1),并返回确认号ack = A.seq + 1;B状态修改为SYN-RCVD(连接已收到)
A:我知道了(ACK=1),并返回并返回确认号ack = B.seq + 1,A状态修改为ESTABLISHED(连接已建立)
B在收到第三次握手后,B状态也修改为ESTABLISHED(连接已建立)

A 与 B 各自在内存中维护着自己的状态变量,三次握手之后,双方的状态都变成了ESTABLISHED(连接已建立).
虽然就只是发了三次数据包,并且在各自的内存中维护了状态变量,但这么说总觉得太 low,你看这个过程相当于双方建立连接的过程,于是你灵机一动,就叫它面向连接吧。

四.三次握手失败后会发生什么?

以下结果摘自知乎回答,详细实验过程去看大佬的回答吧(https://www.zhihu.com/question/36495943/answer/2629057784 作者:小林coding)

第一次握手失败会发生什么?

当客户端发起的 TCP 第一次握手 SYN 包,在超时时间内没收到服务端的 ACK,就会在超时重传 SYN 数据包,
每次超时重传的 RTO 是翻倍上涨的,直到 SYN 包的重传次数到达 tcp_syn_retries 值后,客户端不再发送 SYN 包。
默认为重传5次。

第二次握手失败会发生什么?

当 TCP 第二次握手 SYN、ACK 包丢了后,客户端 SYN 包会发生超时重传,服务端 SYN、ACK 也会发生超时重传。
客户端 SYN 包超时重传的最大次数,是由 tcp_syn_retries 决定的,默认值是 5 次;
服务端 SYN、ACK 包时重传的最大次数,是由 tcp_synack_retries 决定的,默认值是 5 次。

第三次握手失败会发生什么?

在建立 TCP 连接时,如果第三次握手的 ACK,服务端无法收到,则服务端就会短暂处于 SYN_RECV 状态,而客户端会处于 ESTABLISHED 状态。
由于服务端一直收不到 TCP 第三次握手的 ACK,则会一直重传 SYN、ACK 包,直到重传次数超过 tcp_synack_retries 值(默认值 5 次)
后,服务端就会断开 TCP 连接。
而客户端则会有两种情况:
● 如果客户端没发送数据包,一直处于 ESTABLISHED 状态,然后经过 2 小时 11 分 15 秒才可以发现一个「死亡」连接,于是客户端连接就会断开连接。
● 如果客户端发送了数据包,一直没有收到服务端对该数据包的确认报文,则会一直重传该数据包,直到重传次数超过 tcp_retries2 值(默认值 15 次)后,客户端就会断开 TCP 连接。

五.用WireShark去实践三次握手过程

1.下载安装

https://www.wireshark.org/ 一直下一步即可安装

2.双击‘以太网’

在这里插入图片描述

界面出现数据就表示可用了。

3.连接 www.baidu.com,测试三次握手。

打开浏览器,输入百度网址,但是你会发现WireShark界面中数据太多,你压根就找不到哪个是和百度的通信。
此时,你需要这么做:

1)打开cmd,输入命令:ping www.baidu.com,获取到百度的ip为:153.3.238.102

在这里插入图片描述

2.使用WireShark中的过滤功能

在这里插入图片描述

我用的过滤表达式:

(ip.src == 192.168.90.235 || ip.src == 153.3.238.102) 
  && (ip.dst == 192.168.90.235 || ip.dst == 153.3.238.102) 
  && (tcp.port == 53860 || tcp.port == 443)
  && tcp 
  
只显示源ip为我本地ip和百度ip之间的通信
并且,只显示目标ip为我本地ip和百度ip之间的通信
并且,只显示端口为53860和443的通信 (先用上面两个条件过滤一遍,找到这两个端口)
并且,只显示使用TCP传输协议的通信

ip.src:源地址
ip.dst:目的地址
tcp.port:tcp的端口
tcp:传输协议

想了解更多过滤表达式,点击:wireshark 实用过滤表达式

3.界面数据太多,想clear一下,就用清屏快捷键:ctrl+shift+d
4.结果展示并简单分析

在这里插入图片描述

第一次握手:

关注点:
[SYN],
Sequence Number (raw): 2502086410
在这里插入图片描述

第二次握手:

关注点:
[SYN],
[ACK],
Sequence Number (raw): 77720660
Acknowledgment number (raw): 2502086411
在这里插入图片描述

第三次握手:

关注点:
[SYN](去掉了,为什么呢?)
[ACK],
Acknowledgment number (raw): 77720661
在这里插入图片描述

六.为什么需要三次握手,两次不行吗?

最后,也是我最大的疑问,也是面试题经常遇到的:为什么需要三次握手,两次不行吗?
针对历史连接:
现在三次握手来看:有一个老连接,然后又发送了新连接,这时候,服务端先收到了老连接的seq,于是返回给客户端 ACK且ack=老seq+1,客户端收到后,并不是自己想要的,然后返回了RST报错,客户端收到后,就不开启连接了。
如果是二次握手:那就相当于来者不拒,来一个请求,我开一次连接。如果遇到上面的情况,那就造成了无用的历史连接占用服务端资源,造成浪费。对于服务端来说,显然是不可以的。
在我看来,三次握手相当于多加了一层客户端的自检动作。

  • 11
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值