网络基础、TCP/IP 三次握手和四次挥手

网络知识点 OSI 开放式互联参考模型

七层协议

1物理层

  • 解决:机器1向机器2发送比特流,机器2接收比特流。
  • 定义:物理设备的标准,网线类型,设备接口类型,各种传输介质的传输速率
  • 作用:传输比特流010101数据,将比特流转化为电流强弱信号,到达后再转化为0101机器码-> 数模转换和模数转换。网卡定义在这一层

2数据链路层

  • 解决:传输比特流的过程中解决数据传输不完整的可能
  • 定义:如何格式化数据以进行传输以及对物理介质的访问
  • 作用:错误检测和纠正,确保数据传输的可靠性,将比特数据组成了帧,交换机工作在这层,对帧解码,根据帧中的数据发送到网络接收方

3网络层

  • 解决:找到目标节点选择最佳路径,帧数据点对点通信经过多个节点
  • 定义:将网络地址翻译成物理地址并决定将发送方路由到接收方,通过综合考虑选择优先权和最佳路径,TCP/IP 路由器属于网络层,数据为数据包
  • 作用:将数据包切割为一个一个段落进行发送。

4传输层

  • 解决:数据丢失要不要重传,每个段落要按顺序达到么,解决了主机间的数据传输,传输质量的问题
  • 定义:传输协议,流量控制,速率,传输顺序, TCP、UDP

5 会话层

  • 解决:建立和管理应用程序间的通信,解决不同系统之间通信语法的问题,再表示成网络能理解的方案格式化,方案也因为网络的类型不同而不同,
  • 定义: RPC 远程过程调用协议在此层

7 应用层

发送方发送的数据接收方是不知道他的字节数组和内容格式的

  • 解决:规定发送方接收方使用固定的消息头,规定头的组成,消息体的长度,用来正确解析发送的数据,应用从网络中接收到的数据。
  • 定义:TCP/IP 协议对应的 HTTP HTTPS 协议

模型参考

《网络基础、TCP/IP 三次握手和四次挥手》 处理数据

发送方解释数据,分段,分组成帧解释成比特流,通过电缆发送到目标方在向上解析传递。

TCP/IP 模型

OSI概念七层实现:TCP/IP 四层模型
TCP/IP 模型关注应用程序实现,OSI模型在协议开发之前设计的,具有通用性

《网络基础、TCP/IP 三次握手和四次挥手》

《网络基础、TCP/IP 三次握手和四次挥手》

TCP/IP 解释

  • TCP 和 IP 协议
    单独的 TCP IP 协议

  • TCP/IP通信时用到的协议群-网ji协议群
    TCP,UDP 都属于 TCP/IP 协议

    《网络基础、TCP/IP 三次握手和四次挥手》

  • OSI模型注重通信协议必要的功能是什么
  • TCP/IP模型更强调在计算机上实现协议应该开发哪种程序
    一层层包裹在一层层解套出来

TCP 三次握手

传输控制协议TCP

  • 面向连接、可靠、基于字节流的传输层通信协议
  • 将应用层的数据流分割成报文段并发送给目标节点的TCP层
  • 数据包有都有序号,对方接收到则发送ACK 确认,未收到则重传
  • 使用校验和检验数据在传输过程中是否有误

TCP 报文头

《网络基础、TCP/IP 三次握手和四次挥手》

  • 传输中使用协议端口号,ip地址+协议+端口号产生唯一标识网络进程, 也成为套接字 socket。
    source port 原端口,destination port 目的端口
  • Sequence Number 序号字段占4字节
    对每个字节标识,比如一段报文序号107携带100个字段,下一个报文段就是 107 + 100 = 207 开始
  • Acknowledgment Number 期望收到对方下个字节的序号
    例如B收到A 301序号200字节大小的报文段,B接收500字节,B发送给A501 ACK Number,告诉A期望下次接收501序号的报文段

TCP Flage

  • URG: 紧急指针标志 0忽略
  • ACK:确认序号标志1
  • PSH:push 标志 1就有push 将数据尽快交给应用程序而不是缓存区排队
  • RST:重置连接标志
  • SYN:同步序列号1,用户建立连接过程
  • FIN:finish标志,用于释放连接

三次握手

握手是为了建立连接,TCP 三次握手的流程

《网络基础、TCP/IP 三次握手和四次挥手》

第一次握手

  • B服务器创建传输控制块TCP 时刻准备接收客户端进程发送的请求,进入 listen 状态
  • A客户端创建传输控制块TCP向服务器发送连接请求报文 – sent 报文段,SYN同步序号1,seq报文段序号正整数值
  • A客户端进入 SYN-SENT 同步已发送状态,发送的称为 sent 报文段, 不能携带数据,但是要消耗掉一个 seq 序号,这便是第一次握手

第二次握手

  • B服务器接收到请求后如果同意则发送确认接收报文
  • 接收报文包含 SYN1 ACK1 两个字段,而为自己的缓存初始化一个序列号 seq 确认报文序号为 y,ack期待报文序号为 x + 1,因为第一次握手 seq为x
  • 进入 SYN-RCVD 同步收到状态,这时候报文要不能携带数据需要消耗一个 序号

第三次握手

  • TCP 客户端进程A 收到确认报文后还要给服务进程一个报文
  • 确认报文 ACK=1,seq=x+1, ack=y+1
  • 此时TCP 连接建立,客户端进入ESTAB-LISHED 已建立连接的状态,此时ACK报文段可以携带数据(不携带则不消耗序号),之前不可携带数据
  • 服务端进入 SETAB-LISHED 状态 双方就可以通信了。

Wireshark 抓包理解 TCP 三次握手

《网络基础、TCP/IP 三次握手和四次挥手》

win 参数为滑动窗口,进行流量控制

总结三次握手

在 TCP/IP 协议中, TCP 采用三次握手建立可靠的连接。

  • 第一次握手
    建立连接时客户端发送 SYN 包 syn=1 到服务器并进入 SYN_SEND 状态 等待服务器确认
  • 第二次握手
    服务器收到 SYN 包,必须给客户端发送确认包 ACK ack=1,同时发送一个 SYN syn=k,也就是 SYN+ACK 包,此时服务器进入 SYN_RECV 状态
  • 第三次握手
    客户端收到服务器的 SYN+ACK 包后向服务器发送确认包 ACK ack=k+1,此包发送完毕后客户端和服务端后进入 ESTABLISHED 状态,三次握手完毕

    《网络基础、TCP/IP 三次握手和四次挥手》

为什么要三次握手建立连接

  • 初始化 sequence number 的初始值
    通信双方要通知双方 seq num,用来以后通信的序号,保证应用层接收到的数据不会因为网络传输问题导致乱序,TCP用序号拼接数据,而且还要发送确认报文 ack

SYN 超时隐患

首次握手出现

原因

  • server 收到 client 的SYN 回复 SYN-ACK的时候未收到 ACK 确认
  • server 不断重试直至超时,linux 默认63秒等待才断开

目前,Linux下默认会进行5次重发SYN-ACK包,重试的间隔时间从1s开始,下次的重试间隔时间是前一次的双倍,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s, 总共31s, 称为指数退避,第5次发出后还要等32s才知道第5次也超时了,所以,总共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 63s, TCP才会把断开这个连接。由于,SYN超时需要63秒,那么就给攻击者一个攻击服务器的机会,攻击者在短时间内发送大量的SYN包给Server(俗称SYN flood攻击),用于耗尽Server的SYN队列。

恶意攻击 SYN Flood

发送SYN 而不回应,每次都等待63秒,让正常连接不能处理

最基本的DoS攻击就是利用合理的服务请求来占用过多的服务资源,从而使合法用户无法得到服务的响应。syn flood属于Dos攻击的一种。

如果恶意的向某个服务器端口发送大量的SYN包,则可以使服务器打开大量的半开连接,分配TCB(Transmission Control Block), 从而消耗大量的服务器资源,同时也使得正常的连接请求无法被相应。当开放了一个TCP端口后,该端口就处于Listening状态,不停地监视发到该端口的Syn报文,一 旦接收到Client发来的Syn报文,就需要为该请求分配一个TCB,通常一个TCB至少需要280个字节,在某些操作系统中TCB甚至需要1300个字节,并返回一个SYN ACK命令,立即转为SYN-RECEIVED即半开连接状态。系统会为此耗尽资源。

防护措施

  • Syn Cache
    服务端在收到SYN报文时,在一个专用HASH表中保存这种半连接信息,直到收到正确的回应ACK报文再分配TCB。这个开销远小于TCB的开销。还需要保存序列号。

  • Syn Cookie
    1.使用对方的IP、端口、己方IP、端口的固定信息,生成 Sequence Number
    2.SYN 队列满后,通过 tcp_syncookies 参数回发 SYN cookie
    3.若为正常连接则 client 会回发 SYN cookie,直接建立连接分配 TCB 。
    4.攻击者不会回复所以,正常的回复了SYN cookie 就可以在队列外直接建立

建立后 client 出现故障

  • 保活机制
    向对方发送保活探测报文,如果未收到响应则继续发送
    尝试次数达到保活探测数仍未收到响应则中断

连接队列

《网络基础、TCP/IP 三次握手和四次挥手》

在外部请求到达时,被服务程序最终感知到前,连接可能处于SYN_RCVD状态或是ESTABLISHED状态,但还未被应用程序接受。
对应地,服务器端也会维护两种队列,处于SYN_RCVD状态的半连接队列,而处于ESTABLISHED状态但仍未被应用程序accept的为全连接队列。如果这两个队列满了之后,就会出现各种丢包的情形。

sync queue (半连接队列)

  • sync queue 的作用
    三次握手中,第一次握手服务端收到客户端的 SYN 包后,把相关信息放到半连接队列中,同时进行第二次握手回复客户端 SYN + ACK
  • 当 sync queue 满时
    该队列保存服务器已收到客户端的 SYN 包,并向客户发出确认,正在等待客户的确认包。这些所标识的连接在服务器处于 SYN_RECV 状态,当服务器收到客户的确认包时,删除该 SYN 包的信息,服务器进入 ESTABLISHED 状态。

accept queue (全连接队列)

  • accept queue 作用
    第三次握手时服务器收到客户端的 ack,如果这时全连接队列没满,那么从半连接队列拿出相关信息放入到全连接队列中,否则按 tcp_abort_on_overflow 指示的执行。

  • 当 accept queue 满时
    如果全连接队列满了并且 tcp_abort_on_overflow 是 0 直接丢弃该ACK,服务器会进行过一段时间再次进行第二次握手发送 SYN + ACK 给客户端,如果客户端超时等待比较短,就很容易异常。
    tcp_abort_on_overflow 1 表示发送 RST(重置连接) 通知客户端

参考1
参考2

TCP 四次挥手

为了终止连接, 要发送四个包

《网络基础、TCP/IP 三次握手和四次挥手》

1挥手

  • server client 都处于 ESTAB-LISHED 状态
  • client 主动关闭
  • 客户端发送连接释放报文并且停止发送数据
  • 释放报文 FIN=1,seq=u u是最后一个字节的序号+1, 不携带数据也要消耗序号
  • 客户端进入 FIN-WAIT-1

2挥手

  • server 接收到释放报文 发出确认报文
  • 确认报文 ACK=1,seq=v,ack=u+1
  • 进入CLOSE-WAIT状态(重要)半关闭状态,客户端不发送数据,但server 发送的数据 client 还是可以接收

3挥手

  • client 接收到 server 的确认报文进入 FIN-WAIT-2 状态, 等待 server 发送释放连接报文(等待第三次挥手)
  • 此时 client 还要接收 server 发送的最后数据
  • server 发送完最后数据后,发送连接释放报文,FIN=1,ACK=1,seq=w,ack=u+1
  • server 进入 LAST-ACK 最后确认状态

4挥手

  • client 收到释放报文后必须发送确认报文,ACK=1,seq=u+1,ack=w+1
  • client 进入 TIME-WAIT 状态,这时候 client TCP 连接还没释放,必须等待 2MSL(最长报文段寿命liux30s) 才释放
  • server 收到 client 的确认报文后立即关闭,server 比client 稍早点关闭

四次挥手总结

  • 第一次挥手
    客户端发送一个 FIN 序号 seq=u,用来关闭 客户端到服务器的数据传送,客户端进入 FIN_WAIT_1 状态
  • 第二次挥手
    服务器收到 FIN 后,发送一个 ACK 给客户端,确认序号为收到的序号 ack=u+1 FIN 也占一个序号 seq=v,服务器进入 CLOSE_WAITE状态, 这时服务器要把剩下的数据发送完毕
  • 第三次挥手
    服务器剩余数据发送完毕,发送一个 FIN seq=w ack=u+1,用来关闭服务器到客户端的数据传送,服务器进入 LAST_ACK 状态
  • 第四次挥手
    客户端收到 FIN 后,客户端进入 TIME_WAIT 状态,接着发送一个 ACK 给服务器,确认序号为收到序号 ack=w+1和 seq=u+1,服务器进入 CLOSED 状态,客户端等待 2MSL 时间进入 CLOSED 结束。

client TIME_WAIT 状态

等待 2MSL 时间

  • 保证让被动关闭方有足够的时间收到ACK包(确认报文)
  • 如果被动关闭方没有收到则重新发送 FIN 包,一来一回刚好 2MSL
  • 避免新旧连接混淆, 有的路由器缓存的连接跟新连接混淆

为什么要四次挥手才断开连接

双工是允许双向发送,发送方和接收方都需要 FIN 报文和 ACK 报文
各自需要2次挥手,但是一方是被动的,才看上去是4次挥手

服务端出现大量 CLOSE_WAIT

客户端一直请求,但是返回时异常的
当对方发送 FIN 报文后,应用没有返回 ACK
对方关闭 socket 连接,我方忙于读写,没有及时关闭
检查代码,释放资源代码
检查配置,处理请求的线程配置

    原文作者:coolheadedY
    原文地址: https://www.jianshu.com/p/b370164868b8
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞