【计算机网络】 总结复习(2)

news2024/11/25 12:53:56

tcp

tcp 工作在传输层可靠的数据传输服务,确保传输数据是无损坏,无间隔,非冗余按序

一些知识点

  1. 服务端最大并发 TCP 连接数远不能达到理论上限,会受以下因素影响:

    • 文件描述符限制,每个 TCP 连接都是一个文件,如果文件描述符被占满了,会发生 Too many open files。Linux 对可打开的文件描述符的数量分别作了三个方面的限制:
      • 系统级:当前系统可打开的最大数量,通过 cat /proc/sys/fs/file-max 查看;
      • 用户级:指定用户可打开的最大数量,通过 cat /etc/security/limits.conf 查看;
      • 进程级:单个进程可打开的最大数量,通过 cat /proc/sys/fs/nr_open 查看;
    • 内存限制,每个 TCP 连接都要占用一定内存,操作系统的内存是有限的,如果内存资源被占满后,会发生 OOM
  2. TCP 和 UDP 可以使用同一个端口。
    在数据链路层中,通过 MAC 地址来寻找局域网中的主机。在网际层中,通过 IP 地址来寻找网络中互连的主机或路由器。在传输层中,需要通过端口进行寻址,来识别同一计算机中同时通信的不同应用程序。
    传输层有两个传输协议分别是 TCP 和 UDP,在内核中是两个完全独立的软件模块。
    根据IP 包头的「协议号」字段知道该数据包是 TCP/UDP,送给 TCP/UDP 模块的报文根据「端口号」确定送给哪个应用程序处理

三次握手

在这里插入图片描述
三次握手原因:

  1. 阻止重复历史连接初始化
    网络阻塞的情况下可能与历史报文进行连接
  2. 同步双方的序号
  3. 避免资源浪费

每次建立连接初始化序列号均不同,采用随机数+当前时间作为种子的随机数,避免历史连接和syn 伪造

第1次握手丢失

tcp_syn_retries 为 3
当syn 重传次数达到最大重传次数,再等待一段时间(时间为上一次超时时间的 2 倍),如果还是没能收到服务端的第二次握手(SYN-ACK 报文),那么客户端就会断开连接。

第2次握手丢失

tcp_synack_retries 为 5
客户端与服务端均会重传
客户端syn 未收到ack ,情况同第一次握手
服务端报文中包含syn 也需要重传,重传次数由tcp_synack_retries决定

第3次握手丢失

tcp_synack_retries 为 5
服务端会重传
服务端报文中包含syn 也需要重传,重传次数由tcp_synack_retries决定,直至超过重传次数或收到确认

syn 攻击

伪造不同ip的syn 报文,服务端收到会发送synack,将连接添加半连接队列,但由于收不到ack应答会占满半连接队列,导致服务端无法建立连接

避免方法:

  1. 增大tcp半连接队列阈值(增大 net.ipv4.tcp_max_syn_backlog,增大 net.core.somaxconn)
  2. 开启 net.ipv4.tcp_syncookies: 开启 syncookies 功能就可以在不使用 SYN 半连接队列的情况下成功建立连接,相当于绕过了 SYN 半连接来建立连接
  3. 减少 SYN+ACK 重传次数(tcp_synack_retries)
已经建立连接收到syn

如果四元组不同,服务端会认为是一个新的连接进行建立,旧连接由于长时间无应答开启keep alive 探测 关闭。
四元组相同,由于seq 与期待ack 不符,会回复rst

没有accept可以建立连接吗
  • 每一个socket执行listen时,内核都会自动创建一个半连接队列和全连接队列。
  • 第三次握手前,TCP连接会放在半连接队列中,直到第三次握手到来,才会被放到全连接队列中。
  • accept方法只是为了从全连接队列中拿出一条连接,本身跟三次握手几乎毫无关系。
  • 出于效率考虑,虽然都叫队列,但半连接队列其实被设计成了哈希表,而全连接队列本质是链表。
  • 全连接队列满了,再来第三次握手也会丢弃,此时如果tcp_abort_on_overflow=1,还会直接发RST给客户端。
    半连接队列满了,可能是因为受到了SYN Flood攻击,可以设置tcp_syncookies,绕开半连接队列。
  • 客户端没有半连接队列和全连接队列,但有一个全局hash,可以通过它实现自连接或TCP同时打开。

四次挥手

在这里插入图片描述

  • 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
  • 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSE_WAIT 状态。
  • 客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
  • 等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
  • 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
  • 服务端收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。
  • 客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭。
第1次挥手丢失

重传 FIN 报文,重发次数由 tcp_orphan_retries 参数控制,如果超过重传次数,客户端直接进入close 状态

第2次挥手丢失

客户端变成 fin_wait_1,服务端变成close_wait。客户端重传fin 报文(tcp_orphan_retries),如果超过重传次数,客户端直接进入close 状态

第3次挥手丢失

服务端变成last_ack,服务端就会重发 FIN 报文,重发次数仍然由 tcp_orphan_retries 参数控制,这与客户端重发 FIN 报文的重传次数控制方式是一样的。如果超过重传次数,服务端会断开连接
客户端变成fin_wait_2 ,如果在tcp_fin_timeout 时间没有收到第三次挥手,客户端会断开连接

第4次挥手丢失

linux 系统time_wait 会持续2msl进入关闭状态
第四次的ack 丢失,服务端状态为last_ack,客户端为time_wait 。服务端会不断重发fin 报文次数由 tcp_orphan_retries控制。当客户端收到fin报文2msl 会重新计时,直至超过重传次数然后2msl后客户端关闭,服务端关闭

收到乱序fin 如何处理

在 FIN_WAIT_2 状态时,如果收到乱序的 FIN 报文,那么就被会加入到「乱序队列」,并不会进入到 TIME_WAIT 状态。

根据seq序号来判断,等再次收到前面被网络延迟的数据包时,会判断乱序队列有没有数据,然后会检测乱序队列中是否有可用的数据,如果能在乱序队列中找到与当前报文的序列号保持的顺序的报文,就会看该报文是否有 FIN 标志,如果发现有 FIN 标志,这时才会进入 TIME_WAIT 状态。

time_wait

time_wait 2msl 原因:
msl 是报文的最大生存时间,msl 确保历史报文已经自然消亡。设置2msl 是网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待 2 倍的时间。而且2msl 相当于允许ack 丢失一次,fin 再次发送。

time_wait 状态存在的原因:防止历史连接被接受,2msl 确保历史报文已经自动消亡。确保被动关闭方正确关闭。

time_wait 过多会导致,系统资源占用,和端口资源占用
客户端主动发起,无法再与相同四元组建立连接
服务端主动发起,不会导致端口资源受限,它只监视一个端口,但是过多连接会占用系统资源比如fd,内存,cpu等

服务端time_wait 过多:
http(只要有一端没有使用) 没有使用长连接,服务端会主动关闭
http 长连接超时:nginx 就会启动一个「定时器」,如果客户端在完后一个 HTTP 请求后,在一定时间内都没有再发起新的请求,定时器的时间一到,nginx 就会触发回调函数来关闭该连接,那么此时服务端上就会出现 TIME_WAIT 状态的连接。
http长连接连接请求达到上限,nginx 会主动关闭长连接

服务端close_wait 过多:
意味着服务端作为被动关闭方没有调用close函数
一个普通的 TCP 服务端的流程:

  1. 创建服务端 socket,bind 绑定端口、listen 监听端口
  2. 将服务端 socket 注册到 epoll
  3. epoll_wait 等待连接到来,连接到来时,调用 accpet 获取已连接的 socket
  4. 将已连接的 socket 注册到 epoll
  5. epoll_wait 等待事件发生
  6. 对方连接关闭时,我方调用 close
    若没有调用close 大概率是代码写的有问题

time_wait 后收到syn
如果双方开启了时间戳机制:

  • 如果客户端的 SYN 的「序列号」比服务端「期望下一个收到的序列号」要大,并且SYN 的「时间戳」比服务端「最后收到的报文的时间戳」要大。那么就会重用该四元组连接,跳过 2MSL 而转变为 SYN_RECV 状态,接着就能进行建立连接过程。
  • 如果客户端的 SYN 的「序列号」比服务端「期望下一个收到的序列号」要小,或者SYN 的「时间戳」比服务端「最后收到的报文的时间戳」要小。那么就会再回复一个第四次挥手的 ACK 报文,客户端收到后,发现并不是自己期望收到确认号,就回 RST 报文给服务端。

在 TIME_WAIT 状态,收到 RST 会断开连接吗?

  • 如果 net.ipv4.tcp_rfc1337 参数为 0,则提前结束 TIME_WAIT 状态,释放连接。
  • 如果 net.ipv4.tcp_rfc1337 参数为 1,则会丢掉该 RST 报文。

tcp_tw_reuse 为什么默认是关闭
net.ipv4.tcp_tw_reuse,如果开启该选项的话,客户端(连接发起方) 在调用 connect() 函数时,如果内核选择到的端口,已经被相同四元组的连接占用的时候,就会判断该连接是否处于 TIME_WAIT 状态,如果该连接处于 TIME_WAIT 状态并且 TIME_WAIT 状态持续的时间超过了 1 秒,那么就会重用这个连接,然后就可以正常使用该端口了。所以该选项只适用于连接发起方。
net.ipv4.tcp_tw_recycle,如果开启该选项的话,允许处于 TIME_WAIT 状态的连接被快速回收,该参数在 NAT 的网络下是不安全的。因为内网和外网,复用同一个ip 相同的四元祖,会影响其他连接

  • 历史 RST 报文可能会终止后面相同四元组的连接,因为 PAWS 检查到即使 RST 是过期的,也不会丢弃。
  • 如果第四次挥手的 ACK 报文丢失了,有可能被动关闭连接的一方不能被正常的关闭;
关闭函数

关闭函数有两种close 和 shutdown
close 同时socket关闭发送方和接受方。如果多个线程共享同一个socket 当引用次数为0 ,发送fin 报文
shutdown 函数,指定关闭发送方向不关闭读取,若多个线程共享同一个socket ,shutdown不管引用技术直接使socket不可用,发出fin 报文
指定关闭读取不关闭发送,不会fin报文

四次挥手可以变成三次吗

当被关闭方没有数据要发送,且开启延迟确认的机制,那么ack 和 fin 就会合并发送,出现三次挥手。
延迟确认:
解决ack 传输效率过低的问题,linux 系统中打开tcp_quickack

tcp 重传,滑动窗口,流量控制,拥塞控制

tcp 是通过序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输的。

tcp 重传

当对端在指定时间内没有收到确认报文,便会进行超时重传
sack 选择性重传,收到三次相同的ack 便会重发

滑动窗口+流量控制

一种累积应答方式
根据可用窗口进行调整发送速率
在这里插入图片描述
零窗口情况:
接收方向发送方通告窗口大小时,是通过 ACK 报文来通告的。
TCP 为每个连接设有一个持续定时器,只要 TCP 连接一方收到对方的零窗口通知,就启动持续计时器。
如果持续计时器超时,就会发送窗口探测 ( Window probe ) 报文,而对方在确认这个探测报文时,给出自己现在的接收窗口大小。
小窗口问题:
当窗口<min(mss,缓存空间/2) ,会发送零窗口
当发送方发送小数据,使用nagle 算法,思路是延时处理,只有满足下面两个条件中的任意一个条件,才可以发送数据:
条件一:要等到窗口大小 >= MSS 并且 数据大小 >= MSS;
条件二:收到之前发送数据的 ack 回包;

拥塞控制

对网络流量进行控制,避免发送方的数据填充整个网络
通过控制拥塞窗口控制网络的流量,♟策略包括慢启动,拥塞避免,快速重传,超时重传
在这里插入图片描述

tcp 快速建立连接

打开fast open ,会产生cookie,再次连接利用cookie 进行连接(cookie 未过期)

一些故障

进程崩溃

TCP 的连接信息是由内核维护的,所以当服务端的进程崩溃后,内核需要回收该进程的所有 TCP 连接资源,于是内核会发送第一次挥手 FIN 报文,后续的挥手过程也都是在内核完成,并不需要进程的参与,所以即使服务端的进程退出了,还是能与客户端完成 TCP四次挥手的过程

已经连接客户端故障

如果没有开启tcp keepalive 机制,服务端一直处于established 状态占用资源
开启keep alive ,一段时间后服务端会发送探测报文
若对端正常,回复报文,保活时间会重置,重新计时
若对端故障重启,能够相应但是信息不匹配,会产生rst 报文重置连接
若故障,无法接受报文,超过探测次数tcp会宣告死亡

查看网络状态的一些命令

ss 查看tcp 全连接队列的情况
listen 状态:
Recv-Q:当前全连接队列的大小,也就是当前已完成三次握手并等待服务端 accept() 的 TCP 连接;
Send-Q:当前全连接最大队列长度;
established:
Recv-Q:已收到但未被应用进程读取的字节数;
Send-Q:已发送但未收到确认的字节数;

netstat -s | grep “SYNs to LISTEN”
查询tcp 因半连接队列溢出而丢弃

用tcp协议数据一定不会丢吗

存在建立连接丢包,半连接队列满了,全连接队列满了,直接丢包
流量控制丢包,网卡的流控队列长度
网卡丢包,ringbuffer 过小导致丢包,性能不足
接收缓冲区丢包
在这里插入图片描述

ip

tcp 发数据与ping 之间的区别
在这里插入图片描述
从应用层到传输层再到网络层。这段路径跟ping外网的时候是几乎是一样的。到了网络层,系统会根据目的IP,在路由表中获取对应的路由信息,而这其中就包含选择哪个网卡把消息发出。

当发现目标IP是外网IP时,会从"真网卡"发出。

当发现目标IP是回环地址时,就会选择本地网卡。

本地网卡,其实就是个**“假网卡”,它不像"真网卡"那样有个ring buffer什么的,"假网卡"会把数据推到一个叫 input_pkt_queue 的 链表 中。这个链表,其实是所有网卡共享的,上面挂着发给本机的各种消息。消息被发送到这个链表后,会再触发一个软中断**。

专门处理软中断的工具人**“ksoftirqd”** (这是个内核线程),它在收到软中断后就会立马去链表里把消息取出,然后顺着数据链路层、网络层等层层往上传递最后给到应用程序。

结束!
终于整理完了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/499347.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML-CSS学习笔记

day1-01.CSS的元素显示模式 元素的显示模式就是元素&#xff08;标签&#xff09;以什么方式进行展示&#xff0c;比如<div>自己占一行&#xff0c;<span>一行可以放多个。 HTML元素一般分为块元素和行内元素两种类型。 块元素 如果在p标签中放了div标签&#xff…

操作系统——存储管理方式

目录 1.分区存储管理 1-1单一连续分配 1-1-1基本原理&#xff1a; 1-1-2单一连续分区存储管理的地址变换与地址保护 1-1-3管理特点 1-2固定分区分配 1-2-1基本原理 1-2-2分区划分 1-2-3主存空间的分配与回收 1-2-4地址转换与存储保护 1-2-5管理特点 1-3动态分区分配…

软考信管高级——风险管理

风险管理内容 风险管理计划 包含的内容&#xff1a; (1)方法论 (2)角色与职责 (3)预算 (4)时间安排 (5)风险类别 (6)风险概率和影响的定义 (7)概率和影响矩阵 (8)修订的干系人承受力 (9)报告格式 (10)跟踪 风险类型和应对措施 可能遇到的风险&#xff1a; (1)需求风险;(2)技术…

CSS布局基础(精灵图 字体图标 css 三角图标)

精灵图 & 字体图标 精灵图使用字体图标下载字体图标使用方式icomoon阿里 iconfontttf 字体 unicodecss 方式js 方式 更新字体图标icomoon阿里 iconfont css三角图标标准三角&#xff08;垂直的两边相等&#xff09;先来个普通盒子&#xff08;当然是五彩斑斓的边&#xff…

《编程思维与实践》1052.删除注释

《编程思维与实践》1052.删除注释 题目 思路 将所有可能的情况枚举出来: 1.在有效的块注释内: 有效是指块注释不在引号内,如char *s" \ * xxxxxxx *\ "就不是一个有效的块注释, 这种情况下跳过之后所有的内容,直到遇到*/后才重新判断情况; 2.在有效的行注释内: 同理…

ChatGPT :国内免费可用 ChatGPT +Midjourney绘图

前言 ChatGPT&#xff08;全名&#xff1a;Chat Generative Pre-trained Transformer&#xff09;&#xff0c;美国OpenAI 研发的聊天机器人程序 &#xff0c;于2022年11月30日发布 。ChatGPT是人工智能技术驱动的自然语言处理工具&#xff0c;它能够通过理解和学习人类的语言来…

Spring Security 06 Rember Me

目录 基本使用 原理分析 RememberMeServices TokenBasedRememberMeServices 总结 内存令牌 PersistentTokenBasedRememberMeServices 使用内存中令牌实现 持久化令牌 自定义记住我 自定义认证类 LoginFilter 自定义 RememberMeService 配置记住我 RememberMe …

使用多线程执行任务,并获取返回结果,附异步实现

1 获取又返回结果的 需要用到 callable接口 public class TestTask implements Callable<Student> {Overridepublic Student call() throws Exception {Thread.sleep(1500);Student student new Student();student.setAge(10);student.setName("里里");Syste…

Ceph对象存储使用

文章目录 对象存储简介RadosGW简介RadosGW配置RGW使用的存储池配置rgw使用的http端口配置rgw使用https配置rgw高可用 客户端s3cmd测试数据读写创建rgw用户安装s3cmd客户端配置s3cmd访问rgw测试数据读写bucket授权 对象存储简介 对象存储是无层次结构的数据存储方法&#xff0c…

QT+OpenGL反射与折射

文章目录 QTOpenGL反射与折射反射折射 QTOpenGL反射与折射 本篇完整工程见gitee:QtOpenGL 对应点的tag&#xff0c;由turbolove提供技术支持&#xff0c;您可以关注博主或者私信博主 反射 反射这个属性表现为物体(或者物体的一部分)反射它周围的环境&#xff0c;即根据观察者…

【Python入门篇】——Python基础语法(字符串格式化,表达式格式化和数据输入)

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; Python入门&#xff0c;本专栏主要内容为Python的基础语法&#xff0c;Python中的选择循环语句…

STM32CubeMx+HAL库+小熊派+FreeRTOS+EasyLogger+Gitee+手把手教你

文章目录 1、创建工程配置RCC与SYS配置LED配置KEY配置串口生成工程 2、手动移植Freertos获取源码移植include移植portable移植src复制并修改FreeRTOSConfig.hkeil中添加路径与配置 3、移植EasyLogger获取源码复制easylogger文件keil中添加路径修改elog.h修改elog_port.c修改elo…

MacOS自定义安装 Python

Python 下载地址 官网下载太慢&#xff0c;如下是国内的镜像源&#xff0c;各版本都有&#xff1a;Python 国内镜像 下载好后缀是 tgz 的包进行解压 tar -zxvf Python-3.9.16.tgz进入目录并且对进行配置&#xff0c;编译(根据自己的目录进行调整) ./configure --with-opens…

Excel技能之图表,会Excel就能碾压程序员

数据可视化&#xff0c;让数据说话&#xff0c;需要Excel图表的呈现。你越用心&#xff0c;画的图越好看。 同一份数据&#xff0c;用不同的Excel图表展现出来&#xff0c;效果各有千秋。使用正确的图表&#xff0c;从一堆杂乱无章的数据中找出规律。不仅要知道怎么用图表&…

sentinel 随笔 1-流控

0. 想要个半个月的旅游 最近发现算法比较有意思一些&#xff0c;什么企业框架都是看不完的… 书接 FlowSlot 1. FlowRuleChecker.checkFlow() : 配置的规则校验类 sentinel 并没有对这个Checker进行抽象的设计&#xff0c;第一次看有些别扭… package com.alibaba.csp.sent…

矢量绘图UI设计Sketch

Sketch是一款Mac操作系统上常用的矢量图形编辑软件&#xff0c;旨在帮助用户设计和创建高质量的UI和UX界面。 软件安装&#xff1a;Sketch 中文 以下是Sketch软件的一些主要特点&#xff1a; 矢量工具和对象&#xff1a;Sketch提供了多种画线、填充、阴影、文本和形状等矢量工…

Illustrator如何使用图形对象的特殊效果之实例演示?

文章目录 0.引言1.制作毛球小怪物2.制作三维立体图形3.3D剪影球体艺术海报 0.引言 因科研等多场景需要进行绘图处理&#xff0c;笔者对Illustrator进行了学习&#xff0c;本文通过《Illustrator CC2018基础与实战》及其配套素材结合网上相关资料进行学习笔记总结&#xff0c;本…

Unity大面积草地渲染——1、Shader控制一棵草的渲染

大家好&#xff0c;我是阿赵。 这里开始讲大面积草地渲染的第一个部分&#xff0c;一棵草的渲染。按照惯例&#xff0c;完整shader在最后。前面是原理的介绍。 一、准备的资源 这里我自己随便做了一个草的模型&#xff0c;主要是用几个面片搭建的一个简单模型。 然后我准备…

DAP之FLM算法研究

本人所写的博客都为开发之中遇到问题记录的随笔,主要是给自己积累些问题。免日后无印象,如有不当之处敬请指正(欢迎进扣群 24849632 探讨问题); 写在专栏前面https://blog.csdn.net/Junping1982/article/details/129955766 玩过自制DAP工具的一定都知道通过MDK目录的FLM文…

priority_queue

priority_queue&#xff1a;优先队列 头文件还是 < queue> 本质就是堆&#xff1a;完全二叉树 条件&#xff08;任意节点都比其孩子大&#xff08;大根堆&#xff09;&#xff09; priority_queue的默认比较是less&#xff0c;但是建出来的是大根堆&#xff1b;sort排序…