TCP三次握手

2020/03/18

前言

TCP(Transmission Control Protocol)中文叫传输控制协议,是OSI模型传输层的一个协议,是互联网核心协议之一。因为TCP是面向121连接、可靠的协议,所以它的建立连接相对于UDP会复杂很多,经常看到公众号不停地写,大部分都是停留着应试角度,今天我想谈一下自己对TCP三次握手的认识。

TCP特点

TCP有很多特点,其特点是它的设计导致的

  • TCP是基于连接的,数据传输之前需要建立连接,意思就是TCP可以长连接,不是匿名连接
  • 全双工的,表示双向协议,可收可发
  • 字节流的,相对于UDP来说不限制数据大小,打包成报文段传输,最终有序
  • 流量缓冲, 解决通信双方处理能力不匹配
  • 可靠的传输服务,保证可达需要ack,丢包有重发机制
  • 拥塞控制,防止网络出现拥塞,优化传输

基于以上特点我们来聊一聊三次挥手

三次握手

三次挥手是指TCP双方建立连接时需要进行三次发包才能确定连接。为了理解,我们下面用服务端和客户端来表示收发双方

image-20210320171549226

注意规范来讲,图上显示报文传输的不是一条真正的物理连接
真正的物理连接是TCP-网络层-数据链路-物理层,图上这么画只是为了更好地理解

我用1-2,3-4,5-6来表示这三次发包

  1. 首先客户端和服务端刚开始都是处于关闭状态

  2. 然后服务端开始监听端口,客户端开始准备发送1-2消息,我们看一下TCP的包消息结构

    6700E612-B325-48F4-8F67-4B832D710AD5

TCP的报文包接口

从第一层开始,源端口和目的端口,第二层是序号段这里使用seq表示,第三层是确认号这里使用ack表示(注意这里是小写的ack),最后一层是数据包,第四层标红标识位。常用的ACK标识回复(注意这里是大写的ACK),SYN标识同步序号,FIN标识关闭连接。

更多如下表

字段 含义
URG 表示本报文段中发送的数据是否包含紧急数据。URG=1 时表示有紧急数据。当 URG=1 时,后面的紧急指针字段才有效。
ACK 表示前面的确认号字段是否有效。ACK=1 时表示有效。只有当 ACK=1 时,前面的确认号字段才有效。TCP 规定,连接建立后,ACK 必须为 1。(这里和小写的ack区别开)
PSH 告诉对方收到该报文段后是否立即把数据推送给上层。如果值为 1,表示应当立即把数据提交给上层,而不是缓存起来。
RST 表示是否重置连接。如果 RST=1,说明 TCP 连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。
SYN 在建立连接时使用,用来同步序号。当 SYN=1,ACK=0 时,表示这是一个请求建立连接的报文段;当 SYN=1,ACK=1 时,表示对方同意建立连接。SYN=1 时,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中 SYN 才为 1。
FIN 标记数据是否发送完毕。如果 FIN=1,表示数据已经发送完成,可以释放连接。
  1. 1-2发送,客户端初始化包的数据结构,里面包含源端口、目的端口、自己窗口大小、缓冲区等。并且发送SYN=1,ACK=0(这是表示请求报文), 然后随机产生一个seq(假设为x),并且客户端这个时候状态变成syn-sent
  2. 3-4发送,服务端收到消息以后也自己初始化自己的包数据结构,然后给给刚刚那个客户端也回复一个SYN=1和ACK=1(表示同意建立连接报文),然后随机生成一个seq(假设为y)并且ack设置为客户端发过来的seq+1(x+1),回复大写ACK是表示这个是回复确认的报文段,回复小写ack是表示这个下次希望能收到这个序号的报文段。
  3. 5-6发送,客户端这个时候,已经收到服务端的ACK了,其实服务端这个时候只收到过对方客户端发过来的消息,还不知道它是能正常接收,刚刚发的消息客户端是否收到,所以5-6其实是客户端给服务端回复ack告诉服务端它已经收到消息,我的接收消息能力是正常的,并且回复的ACK值=1并且ack设置成刚刚发过来的seq+1(y+1),同时发送一个序列号seq为上次发送的seq+1(x+1).
  4. 此时,双方的接受和发送能力都是知道了,可以确立连接。
  5. ps: 为了保证一方出现故障,对方一直等下去,白白浪费资源的情况。TCP里面设有一个保活计时器,每次收到消息就会复位这个计时器,并且长时间没有接收到消息,会发送一个检测报文,如果连续十个检测报文都没有ACK回复,则会关闭连接。

查看TCP连接报文信息

干讲其实还是理解其实比较枯草,还不如被公众号的文章,我们可以通过终端来进行抓取TCP的包,查看他们建立连接的发送的报文信息,其中需要用到的命令如下

// tcpdump命令 是一款抓包,嗅探器工具
tcpdump -i 网卡 -S -c 3 port 5555
// 其中-表示指定网卡,-c 表示接收到多少次以后就停止监听 port表示监听的端口

// nc命可以通过 TCP 和 UDP 在网络中读写数据
nc 对方ip 端口
  1. 先找到自己的网卡

    image-20210320174547421

选取自己的网卡
  1. 设置服务端监听

    image-20210320174745938

我监听的是5555端口
  1. 打开客户端,然后输入服务端的端口,用nc建立连接

    image-20210320174943405

可以看到,连接后服务端就关闭连接了(因为-c设置了3)
  1. 我们可以看到其中的seq值,每次是+1的,还有一些ack信息
  2. 我们还可以使用下面命令,来看系统的一些tcp建立
// 查看Linux中网络系统状态信息,t是筛选tcp,p是显示端口,n是数字显示,C是刷新时间
netstat -tpn -C 1

image-20210320175445086

可以看到后台有大量的进程使用tcp通信

(转载本站文章请注明作者和出处 没有气的汽水



┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
├ 文章已经完啦, 想要第一时间收到文章更新可以关注↓ ┤
└┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┘

Post Directory






下面是评论区,欢迎大家留言探讨或者指出错误哈