【计算机网络】Tcp详解
文章目录
- 前言
- Tcp协议段格式
- TCP的可靠性
- 面向字节流
- 应答机制
- 超时重传
- 流量控制
- 滑动窗口(重要)
- 拥塞控制
- 延迟应答
- 捎带应答
- 标志位
- 具体标志位
- 三次握手
- 四次挥手
- 粘包问题
- TCP异常情况
- listen的第二个参数
前言
前面我们学习了传输层协议Udp,今天我们一起学习Tcp,Tcp比Udp复杂,但可靠,非常多的场景需要这种可靠。
Tcp协议段格式
只从格式来看,Tcp就比Udp复杂许多,那么Tcp的报头和有效载荷应当如何分离?
首先,报头前20个字节一定是固定的,我们先提取前20个字节,找到4位首部长度
然后,首部长度 * 4 -20,来查看是否有选项
最后,读完选项的字节,剩下的就是数据。
TCP的可靠性
大量丢包,乱序,重复,校验失败,发送缓慢,网络故障,都是不可靠的表现,正是因为传输距离变长,才会引发如此多的可靠性问题,为了解决这些问题。TCP引入了应答进制。
假如C给S发送了一条数据,只有当S给C了应答,C才认为自己的数据已经送到了S的手里,如果等待一段时间后没有收到这个应答,C就会认为自己发送的数据丢失了,会触发超时重传。
为了提高发送的效率,多个TCP报文会同步传送,这也就导致到达对端的数据没有顺序,而乱序正是我们要可靠问题,所以TCP报文注定是有编号的
面向字节流
应用层将数据拷贝到TCP的发送缓冲区,以 uint8 为一个单位将整个发送缓冲区划分。所以发送缓冲区天然带编号(数组下标)。
应答机制
上面我们知道TCP需要应答和编号,应答其实就是一个TCP报文中携带了ACK字段,而32位序号就是我们所说的编号,对端需要针对这个序号对我们做出ACK应答。
例如:C端发出了32位序号为10的报文,S端就要返回一个32确认编号为11的报文
发送序号:当前报文的编号。
确认序号:表示前面的报文已经全部收到,接下来应该从这个序号开始发送了。
由于Tcp报文具有捎带应答机制,即S发送ACK的时候,也有想要发给C的信息,所以必须设计为两个独立字段,而不能复用在一起。
超时重传
数据丢失的两种可能性:
1、数据半路真的丢包了
2、数据没有丢包,但ACK半路丢了
第一种情况,必然需要我们重传数据,也就要求TCP必须能做到暂时保存这些数据,以支持重传。
第二种情况,可以参考其他的ACK,因为如果只是ACK丢失,其他ACK的确认序号不会变。
等待时间:各个平台不同,在linux下以500ms为基准,n*500的方式动态调整。
流量控制
TCP具有接收缓冲区和发送缓冲区,也是全双工的,但只要是缓冲区就有大小,设想一下这样的场景:
C将报文送到了S,但S的接收缓冲区放不下了。在这种情况下,S只能丢弃掉来的报文,并不做应答,过一段时间,C会进行重传操作。
仔细一下就会发现这样是十分低效的,报文千里迢迢赶到对端主机,却因为对端没法接收而被丢弃,为了解决这个问题,TCP报文有一个叫做16位窗口大小的字段,这个字段填充自己的接收缓冲区的大小,对方拿到报文时就会看到这个大小,并根据此大小调整(增大或减小)发送数据的速度、大小。
窗口探测:
双端会定期向对方发送不携带数据的TCP报文,以此来询问对方的接收能力,调整自己发送数据的速度和大小(这个过程是双向的)
滑动窗口(重要)
TCP协议,可靠性是主要的研究问题,但效率问题,也是TCP需要考虑的问题。
发送方并发发送,一定要在对方能够接收的前提条件下,才能进行并发发送。
1、一般情况
一个发送缓冲区就被滑动窗口划分成了三个区域。
左边的区域:已经发送,且已经确认的数据——可以被覆盖的
中间的区域:可以直接发送(大小限制),但尚未收到应答
右边的区域:尚未发送的数据区域
滑动窗口的大小,应该与与对方的接收能力有关。
1.5、如何理解滑动窗口
2、特殊情况
1、滑动窗口只能向右,因为左边的数据已经没有了意义
2、变大变小本质是在调整winend,取决于对方的窗口大小,滑动窗口是浮动的
3、变成0,说明对方不能接收数据了(进行窗口探测,窗口通知)
4、应答也要按序到达
应答编号:winstart = seq;
应答窗口大小:winend = winstart + win;
5、丢失问题
a、第一个丢失了
重传补发
b、中间的丢失了
向右滑动,又变成了第一个丢失
c、最后一个丢失
也会变成最左侧丢失
快重传:(高速重发)
当某一个报文丢失,连续收到了三个一样的确认应答后,立马进行重传。
重传的下限:超时重传
重传的上限:快重传
拥塞控制
如果网络出现问题,TCP也进行了策略控制。
同样都是丢包,丢少和丢多也是不一样的,如果一直在丢包,那就是网络的问题。
当大量丢包的时候,发送方的发送策略是 等等再发!!
如果网络出现瘫痪的时候,所有主机再次重传,会让瘫痪的网络更难以恢复,所以我们采用的策略是,如果发现了网络拥塞,要减少发送量。总的来说要符合以下两点要求:
1、保证网络拥塞不能加重
2、在网络恢复有起色时,尽快恢复网络通信
TCP引入了 慢启动 机制:
发生了网络拥塞,发送方要基本得知网络拥塞的严重程度,必须进行网络状态的探测
拥塞窗口
需要对网络状况进行衡量——拥塞窗口
网络状态时变化的,衡量网络健康状态,即拥塞窗口的大小一定是变化的。
因此发送方的滑动窗口 = min(16位窗口大小,网络的拥塞窗口)
拥塞窗口的增长速度是指数级别的,慢启动指的是前期慢,后期增长速度非常快。
1、慢启动有一个阈值
2、当拥塞窗口超过这个阈值后,不再指数增长,而是按线性增长
3、每次超时重发的时候,慢启动阈值(ssthresh)会变成原来的一半,同时拥塞窗口置为1(乘法减少)
延迟应答
立即返回ACK应答,返回的窗口大小可能会比较小。
给对方通告出更大的win大小,对方就能在更大概率上提高传送效率。给上层更多时间来读取,在这段时间尽快读取,且读取更多。
捎带应答
ACK搭顺风车。
标志位
- 标志位的本质
一个二进制位,来标识不同类型的报文
- 为什么要有标志位
不同的标志位提供不同的服务。
具体标志位
ACK:确认应答报文,可能携带数据(捎带应答)
SYN:连接请求的报文(三次握手)
FIN:连接断开的报文(四次挥手)
PSH:提示对方应用层尽快将缓冲区数据取走(多路转接
)
RST:告诉对方要重新连接(连接被重置了)
URG:按序到达,但我们想插队?(紧急数据)16位紧急指针,紧急数据在有效载荷中的偏移量。紧急数据(带外数据)只有一个字节。(下载取消案例)recvfrom的MSG_OOB选项。
三次握手
-
1、什么是连接?
一个OS内一定右多个建立好的连接,OS必须要把这些连接管理起来。
维护连接是有成本的,必然要消耗CPU、内存资源。 -
2、为什么是三次?
三次握手过程,由双方操作系统在TCP自主完成
connect:触发连接,等待完成
accept:等待建立完成,获取连接对于客户端来说,只要发出了最后一个ACK,就认为链接已经建立好了。
对于服务端来说,只有收到了最后一个ACK,服务器才消耗资源构建。因此,三次握手本质在赌服务端的确收到了最后一个ACK。假如没有收到ACK,两者建立认知不一致了,这时候客户端再给服务端发消息,服务端就会回复一个RST,进行连接重置
- 如果两次握手,只要发出SYN+ACK就得浪费资源构建。容易被
SYN洪水攻击
。注意,TCP本身并不考虑解决安全问题,但TCP不能出现安全漏洞!因此需要规避SYN洪水。 - 如果大于3次握手,仍然解决不了最后一个ACK问题,如果是偶数次握手,最后一个ACK是服务器端承担风险、奇数次握手是客户端承受风险。而服务器端保存着大量的数据,出现异常是必然的,固而两次以及偶数握手是不妥的
- 3次握手的好处:
1、没有明显漏洞,出现异常,成本嫁接到客户端
2、验证双方通信信道通畅情况,是验证流畅(全双工)的最小成本(收、发)
- 如果两次握手,只要发出SYN+ACK就得浪费资源构建。容易被
-
3、状态变化
SYN_SENT:同步发送
SYN_RCVD:同步收到
ESTABLiSH:建立完成
四次挥手
四次挥手,是双方建立连接断开共识的最小成本!必须要双方同意(都不发消息)!
状态变化:
当客户端退出,服务器端不调用close的时候,服务端进入CLOSE_WAIT状态,服务端进入FIN_WAIT2的状态。
一段时间后,客户端的FIN_WAIT2消失,服务端仍是CLOSE_WAIT状态。所以,对于服务器端,要关掉文件描述符!
调用close后,服务器端立马进入LAST_ACK状态,并发送FIN给对端,如果对端已经关闭,在经历几次重传后,服务器端也会断开连接。
主动断开的一方,要进入TIME_WAIT状态,此时立马想要重启,会失败,原因是底层连接还在,正处于TIME_WAIT状态。
-
1、为什么要进入TIME_WAIT
TCP协议规定,主动断开连接的一方,要等待两个MSL时间(一个报文在网络里存在的最大时间),
- 1、让网络中的报文尽快消散,防止对新的连接产生影响。
- 2、保证最后一个ACK让对方收到。对方如果没收到最后一个ACK,会再发送FIN。
-
2、如果server不想等待
//设置地址可以复用,令服务器立马重启 setsockopt(int sockfd,int level,int optname,const void* optval,socklen_t optlen) 参数: sockfd:套接字 level:当前在哪一层(SOL_SOCKET) optname:(SO_REUSEADDR | SO_REUSEPORT) optval:1 optlen:len
粘包问题
TCP没有UDP里面的报文长度字段,我们并不知道两个数据的边界,这样的问题就是粘包问题
解决:明确两个包之间的边界(上层去完成)。
TCP异常情况
进程终止/机器重启:进程终止会释放文件描述符,仍然发送FIN,和正常关闭一样(操作系统回收所有相关资源)
机器掉电/网线断开:对端认为连接还在,一旦接收端有写入操作,发现连接不在了,就会reset,服务器发送保活定时器,发送端也可reset
listen的第二个参数
设置第二个参数为1,连接服务器,一定程度后,进入SYN_RECV,即已经建立好的链接只能是两个。
TCP协议,需要在底层维护全连接队列,最大长度为:第二个参数 + 1
将没有连接到半连接队列,时间非常断。
全连接队列不能太长,也不能没有。全连接的长度不是服务器处理的长度,而是一个 “排队” 的地方.
1、会消耗过多的OS资源,不如给server使用
2、尾部等待太长。
相关文章:

【计算机网络】Tcp详解
文章目录 前言Tcp协议段格式TCP的可靠性面向字节流应答机制超时重传流量控制滑动窗口(重要)拥塞控制延迟应答捎带应答标志位具体标志位三次握手四次挥手粘包问题TCP异常情况listen的第二个参数 前言 前面我们学习了传输层协议Udp,今天我们一…...
最简单的laravel不使用任何扩展导出csv
php导出csv是非常常用的操作,网上也有灰常多的扩展。如果只是单纯的导出csv数据,完全没有必要去用扩展。现在做项目,都是代码能少就少,扩展能不用就不用。好了,不废话了,开干! 直接搞一个方法&…...

Android studio 断点调试、日志断点
目录 参考文章参考文章1、运行调试2、调试操作3、断点类型行断点的使用场景属性断点的使用场景异常断点的使用场景方法断点的使用场景条件断点日志断点 4、断点管理区 参考文章 参考文章 1、运行调试 开启 Debug 调试模式有两种方式: Debug Run:直接…...

服务器数据恢复-热备盘同步过程中硬盘离线的RAID5数据恢复案例
服务器数据恢复环境: 华为OceanStor某型号存储,11块硬盘组建了一组RAID5阵列,另外1块硬盘作为热备盘使用。基于RAID5阵列的LUN分配给linux系统使用,存放Oracle数据库。 服务器故障: RAID5阵列1块硬盘由于未知原因离线…...
Python 使用input获取用户输入
视频版教程 Python3零基础7天入门实战视频教程 input()函数用于向用户生成一条提示,然后获取用户输入的内容。由于input()函数总会将用户输入的内容放入字符串中,因此用户可以输入任何内容,input()函数总是返回一个字符串。我们可以通过int(…...

Python 可迭代对象、迭代器、生成器
可迭代对象 定义 在Python的任意对象中,只要它定义了可以返回一个迭代器的 __iter__ 魔法方法,或者定义了可以支持下标索引的 __getitem__ 方法,那么它就是一个可迭代对象,通俗的说就是可以通过 for 循环遍历了。Python 原生的列…...

HTML的有序列表、无序列表、自定义列表
目录 背景: 过程: 有序列表: 简介: 代码展示: 效果展示: 无序列表: 简介: 代码展示: 效果展示: 自定义列表: 简介: 代码展示: 效果展示: 总结: 背景: 1.有序列表(Ordered List): 有序列表是最早的…...

银河麒麟安装Docker-国产化-九五小庞
银河麒麟高级服务器操作系统 V10 是针对企业级关键业务,适应虚拟化、 云计算、大数据、工业互联网时代对主机系统可靠性、安全性、性能、扩展性和 实时性的需求,依据 CMMI 5 级标准研制的提供内生安全、云原生支持、国产 平台深入优化、高性能、易管理的…...

数据库与身份认证
1. 数据库的基本概念 1.1 什么是数据库 数据库(database)是用来组织、存储和管理数据的仓库。 当今世界是一个充满着数据的互联网世界,充斥着大量的数据。数据的来源有很多,比如出行记录、消费记录、浏览的网页、发送的消息…...

LabVIEW开发锅炉汽包水位的监督控制和模拟
LabVIEW开发锅炉汽包水位的监督控制和模拟 控制锅炉汽包液位对于机械的安全和设备的保护至关重要。滚筒液位控制器的工作是将滚筒液位提高到指定的设定点,并保持在那里,同时保持一致的蒸汽负荷。锅炉管可能会因该水平急剧下降而暴露,这会导致…...
2023-简单点-树莓派安装ncnn框架
not python 按照下面的步骤进行就可以了: 参考 tips: 其中有一步要用下面方法: 如果你的git clone不得行,可以按照以下操作方法: git clone --depth1 https://ghproxy.com/ https://github.com/Tencent/ncnn.git python 直接 pip install …...

Docker核心原理与实操
第一章、Docker基本概念 1、概念:Docker是一种容器技术,可以解决软件跨环境迁移问题。 2、实现原理:是一个分层复用的文件系统;每一层都是一个独立的软件; …...
虚幻引擎 UE5 增强输入系统
用人话讲!虚幻引擎 UE5 增强输入系统(蓝图篇)_酥妃大魔王i的博客-CSDN博客 UE5 -- EnhancedInput(增强输入系统) - 知乎 (zhihu.com) 简单认识 虚幻引擎中的增强输入 | 虚幻引擎5.1文档 (unrealengine.com) 文档有较详细介绍 标记一下方便…...

Mac 安装软件各种报错解决方案
Mac 安装软件各种报错解决方案 文章目录 Mac 安装软件各种报错解决方案一. 打开允许“允许任何来源”二. 无法打开"xxx",因为它不是从App Store下载三. 无法打开"xxx",因为 Apple无法检查其是否包含恶意软件。四. "xxx"已…...
leetcode做题笔记142. 环形链表 II
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整…...

DuDuTalk:4G语音工牌,如何实现家庭上门维修服务过程的智能化管理?
随着上门按摩、上门养老、上门买菜、上门维修等互联网上门服务的兴起,越来越多的居民开始采用线上下单,享受企业安排人员上门到家的服务。而家庭维修作为到家服务里面典型的一个场景,已成为许多人不可或缺的一部分。然而,与此同时…...

Mybatis常见面试题总结
梳理面试过程中Mybatis相关的常见问题。为保证知识点覆盖,参考了《Mybatis从入门到精通》、《深入浅出Mybatis技术原理与实战》、《Mybatis技术内幕》等书籍。 Mybatis 简介 Mybatis 是一款优秀的持久层框架(ORM框架),它支持自定义SQL、存储过程以及高…...

数字IC设计之时序分析基础概念汇总
1 时钟Clock 理想的时钟模型是一个占空比为50%且周期固定的方波。时钟是FPGA中同步电路逻辑运行的一个基准。理想的时钟信号如下图: 2 时钟抖动Clock Jitter 理想的时钟信号是完美的方波,但是实际的方波是存在一些时钟抖动的。那么什么是时钟抖动呢?时钟抖动&#…...

1.centos7安装docker
本文目录: 1.docker 安装1.安装步骤2.安装是否成功校验3.docker加速配置4.hello world来袭,验证安装是否ok 2.卸载docker3.卸载较旧版本docker 使用docker必备的三个官方网站: docker官网:https://www.docker.com docker官方仓库&…...

基于elasticsearch-8.8.2 kibana-8.8.2 搭建一个文搜图系统demo
数据来源是由 图片url,图片descript,图片keywords 外加一个id 基于此首先创建 索引, keywords是一组由单词或词组 组成的一组数据,所以以数组形式压入数据: descript 是由两条语句组合成的数据(针对图片的两种不同描述) # 这里创建的keywords 数组元素类型为text,即可以模糊匹…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...

动态规划-1035.不相交的线-力扣(LeetCode)
一、题目解析 光看题目要求和例图,感觉这题好麻烦,直线不能相交啊,每个数字只属于一条连线啊等等,但我们结合题目所给的信息和例图的内容,这不就是最长公共子序列吗?,我们把最长公共子序列连线起…...