TCP相关概念

news2024/11/26 17:25:00

目录

一.滑动窗口

1.1概念

 1.2滑动窗口存在的意义

1.3 滑动窗口的大小变化

 1.4丢包问题

二.拥塞控制

 三.延迟应答

四.捎带应答

五.面向字节流

六.粘包问题

七.TIME_WAIT状态

八.listen第2个参数

九.TCP总结


一.滑动窗口

1.1概念

概念:双方在进行通信时,一方可以一次性向另一方发送多条消息,这样可以将等待多个响应的时间重叠起来,进而提高数据通信的效率。

 窗口大小指的是无需等待确认应答而可以继续发送数据的最大值,操作系统内核为了维护这个滑动窗口, 还需要开辟发送缓冲区 ,只有确认应答过的数据, 才能从缓冲区删掉。

其实可以将发送缓冲区当中的数据分为三部分:

  • 已经发送并且已经收到ACK的数据。
  • 已经发送还但没有收到ACK的数据。
  • 还没有发送的数据。

 1.2滑动窗口存在的意义

可以提高传输数据的效率

滑动窗口的大小等于对方窗口大小与自身拥塞窗口大小的较小值,因为发送数据时不仅要考虑对方的接收能力,还要考虑当前网络的状况。可以一次性发送多条消息,将多个等待时间重叠起来,滑动窗口越大,则网络的吞吐率越高,同时也说明对方的接收能力很强。

1.3 滑动窗口的大小变化

滑动窗口不一定会整体右移,会根据对方的接受能力不断改变。一般情况下滑动窗口是向右移动,说明对方接受能力稳定。如果对方不接收或16位窗口大小变小了,说明对方接受能力变小,滑动窗口会变小,即:start_index 会向右走,end_index不动;如果对方返回的16位窗口大小变大了,说明对方接受能力变大,滑动窗口会变大,即:start_index不动 ,end_index向右走。

 1.4丢包问题

如果一次性发送多条数据,出现丢包了,该如何解决呢?

情况一:数据被对方接受了,但自己未收到对方ACK应答

 这种情况相对好点,即使前面几条ACK应答丢了,但只要自己收到了较大的ACK应答(确认序号更大),就说明在收到的较大ACK应答对应的那条数据以及之前的数据,对方都接受到了。

情况二:数据未被对方接受到。那么直接进行重新发送。

在上面的那个例子中如果发送端主机连续三次收到了同样一个 "1001" 这样的应答, 就会将对应的数据 1001 - 2000 重新发送;

这个时候接主机B收端收到了 1001 之后, 再次返回的ACK就是7001了,因为之前的数据都已经收到了, 被放到了接收端操作系统内核的接收缓冲区中,这种机制被称为 "高速重发控制"(也叫 "快重传").

二.拥塞控制

如果双方在进行通信过程中,发生了大量的丢包问题,那么可能就是网络出现了问题。

如何去解决呢?

能否用滑动窗口解决:因为网络上有很多的计算机, 可能当前的网络状态就已经比较拥堵. 在不清楚当前网络状态下, 贸然发送大量的数据,是很有可能会进一步导致问题更严重。能否进行重传:一样,再次向网络上输入数据,就可能造成更严重的问题。

解决方法:

TCP引入 慢启动 机制, 先发少量的数据, 探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输数据,  此处引入一个概念程为拥塞窗口,定义:在拥塞窗口发送数据量以内不会拥塞,超过可能会引发拥塞问题。

例如,当出现拥塞时,将拥塞窗口定义为一个较小的值,当能收到ACK应答时,在不断去增大这个拥塞窗口(以指数级别)。滑动窗口的大小= min(对方的窗口大小,拥塞窗口)

补充:

在慢启动时是以指数级别增加的,增加到一定程度时,会线性增长。

此处引入一个叫做慢启动的阈值,当拥塞窗口超过这个阈值的时候, 不再按照指数方式增长, 而是按照线性方式增长。当TCP刚开始启动的时候,慢启动阈值设置为对方窗口大小的最大值。在每次超时重发的时候,慢启动阈值会变成当前拥塞窗口的一半,同时拥塞窗口的值被重新置为1,如此循环下去。

 三.延迟应答

当接受数据的一方收到数据后,不要立即进行ACK应答。(实际接收端处理数据的速度很快,可能在很短额时间内就将接受缓冲区内的数据读取了)接收端稍微等一会再进行ACK应答,比如等待200ms再应答,那么这时返回的ACK应答中窗口大小就能更大。

此外,不是所有的数据包都可以延迟应答。

  • 数量限制:每个N个包就应答一次。
  • 时间限制:超过最大延迟时间就应答一次(这个时间不会导致误超时重传)。

延迟应答具体的数量和超时时间,依操作系统不同也有差异,一般N取2,超时时间取200ms。

四.捎带应答

概念:当一方要给另一方发送响应时,同时也要给对方发送消息,那么二者可以一起发送,双方通信时就不是单独发送确认报文,单独发送ACK响应,这样也增大了传输效率。

五.面向字节流

在创建一个TCP的socket时,同时在内核中会创建一个发送缓冲区和一个接收缓冲区。由于缓冲区的存在,发送数据的方式和数据的格式完全无关系,即TCP程序的读和写不需要匹配。

  1.调用write时, 数据会先写入发送缓冲区中, 如果发送的字节数太长, 会被拆分成多个TCP的数据包发出。 如果发送的字节数太短, 就会先在缓冲区里等待, 等到缓冲区数据有一定数量了, 或者其他合适的时机发送出去。(调用write可以认为是在拷贝数据到相关内核中,具体什么时候发送是由操作系统决定的

 2.在接收数据的时候, 数据也是从网卡驱动程序到达内核的接收缓冲区,然后应用程序可以调用read从接收缓冲区拿数据;

 TCP既有发送缓冲区, 也有接收缓冲区, 那么对于这一个连接, 既可以读数据, 也可以写数据. 这个概念叫做 全双工

例如:

写100个字节数据时,可以调用一次write写100字节,也可以调用100次write,每次写一个字节。

读100个字节数据时,也完全不需要考虑写的时候是怎么写的,既可以一次read100个字节,也可以一次read一个字节,重复100次。

六.粘包问题

这个概念是在应用层上的。因为TCP通信是面向字节流的,

在TCP的协议头中, 没有如同UDP一样的 "报文长度" 这样的字段, 但是有一个序号这样的字段。站在传输层的角度,TCP的报文是按照序号排好序放在缓冲区中,站在应用层的角度, 看到的只是一串连续的字节数据。

如何解决呢?

要解决粘包问题,本质就是要明确报文和报文之间的边界。

对于定长的包,保证每次都按固定大小读取即可。
对于变长的包,可以在报头的位置,约定一个包总长度的字段,从而就知道了包的结束位置。比如HTTP报头当中就包含Content-Length属性,表示正文的长度。
对于变长的包,还可以在包和包之间使用明确的分隔符。因为应用层协议是程序员自己来定的,只要保证分隔符不和正文冲突即可。

UDP协议来说, 是否也存在 "粘包问题" 呢?

不存在,因为UDP协议是面向数据报的。

面向数据报:当应用层交给UDP多长的报文,UDP就原样发送,既不会拆分,也不会合并,这就叫做面向数据报 ,不能够灵活的控制读写数据的次数和数量。

因为UDP报头当中的16位UDP长度记录的是UDP报文的长度,因此UDP在底层的时候就把报文和报文之间的边界明确了,而TCP存在粘包问题就是因为TCP是面向字节流的,TCP报文之间没有明确的边界。站在应用层的角度,使用UDP的时候,要么收到完整的UDP报文,要么不收,不会出现“半个”的情况。

七.TIME_WAIT状态

前面已经介绍了,双方在通信过程中,主动断开连接的一方,在完成4次挥手后,不会立即进入CLOSED状态,而是进入短暂的TIME_WAIT状态等待若干时间,最终才会进入CLOSED状态。

若是服务器先断开连接,在TIME_WAIT的时间里,该连接处于TIME_WAIT期间,如果服务器想要再次重新启动,就会出现绑定失败的问题(绑定同一个端口号)。因为在TIME_WAIT期间,这个连接并没有被完全释放,也就意味着服务器绑定的端口号仍然是被占用的,此时服务器想要继续绑定该端口号启动,就只能等待TIME_WAIT结束。

解决办法:setsockopt,让服务器在调用socket函数创建套接字后,继续调用setsockopt函数设置端口复用。

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

参数解释:

sockfd:需要设置的套接字对应的文件描述符。
level:被设置选项的层次。比如在套接字层设置选项对应就是SOL_SOCKET。
optname:需要设置的选项。该选项的可取值与设置的level参数有关。
optval:指向存放选项待设置的新值的指针。
optlen:待设置的新值的长度

例如:

int opt = 1;
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

八.listen第2个参数

创建TCP服务端流程:套接字创建、绑定、监听,调用accept函数。

TCP在进行连接管理时会用到两个连接队列:

  • 全连接队列(accept队列)。全连接队列用于保存处于ESTABLISHED状态,但没有被上层调用accept取走的连接。
  • 半连接队列。半连接队列用于保存处于SYN_SENT和SYN_RCVD状态的连接,也就是还未完成三次握手的连接。

一般全队列的长度是等于listen的第2个参数的值+1.

意义:服务器启动一般会启动多个线程(数量也是有限的),主线程从底层accept上来连接后就可以将其交给这些服务线程进行处理。当所有线程都在运行时,维护一个全队列,不会直接拒接客户端的连接请求,而是在一些线程空闲时在accept这些全队列中的请求。

九.TCP总结

可靠性:

  • 检验和。
  • 序列号。
  • 确认应答。
  • 超时重传。
  • 连接管理。
  • 流量控制。
  • 拥塞控制。

提高性能: 

  • 滑动窗口。
  • 快速重传。
  • 延迟应答。
  • 捎带应答。

TCP的各种机制实际都没有谈及数据真正的发送,这些都叫做传输数据的策略。TCP协议是在网络数据传输当中做决策的,它提供的是理论支持,比如TCP要求当发出的报文在一段时间内收不到ACK应答就应该进行超时重传,而数据真正的发送实际是由底层的IP和MAC帧完成的。


 

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

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

相关文章

2023年软考高级-系统分析师考试学习指导计划!

2023年软考高级-系统分析师考试学习指导计划! 一、导学阶段 第一天 考试情况及备考攻略:https://www.educity.cn/xuanke/rk/rjsp/?sywzggw 考试介绍:https://www.educity.cn/wangxiao2/c410653/sp110450.html 考试经验分享:h…

如何在Linux中优雅的使用 head 命令,用来看日志简直溜的不行

当您在 Linux 的命令行上工作时,有时希望快速查看文件的第一行,例如,有个日志文件不断更新,希望每次都查看日志文件的前 10 行。很多朋友使用文本编辑的命令是vim,但还有个命令head也可以让轻松查看文件的第一行。 在…

记录使用chatgpt的复杂经历

背景 由于最近要写论文,c站的gpt也变样了,无奈之下和同学借了一个gpt账号,才想起没有npv,不好意思去要,也不想买,于是我找了很多临时免费的直到我看到有一家,邀请10人即可,而且只用…

江苏专转本 专科生的最好出入

专转本 专科生的最好出入(1) 减少每天刷某音,刷朋友圈的时间无所事事、捧着手机刷的不是某音就是朋友圈,三年下来没去成一次图书馆。碎片化信息很大程度只是在浪费时间,不如每天比同龄人至少多出1小时时间,用来看书、护肤、健身。…

磨金石教育摄影技能干货分享|高邮湖上观花海

江苏高邮,说到这里所有人能想到的,就是那烟波浩渺的高邮湖。高邮在旅游方面并不出名,但是这里的自然人文景观绝对不输于其他地方。高邮不止有浩瀚的湖泊,春天的油菜花海同样壮观。春日的午后,与家人相约游玩&#xff0…

C语言--字符串函数1

目录前言strlenstrlen的模拟实现strcpystrcatstrcat的模拟实现strcmpstrcmp的模拟实现strncpystrncatstrncmpstrstrstrchr和strrchrstrstr的模拟实现前言 本章我们将重点介绍处理字符和字符串的库函数的使用和注意事项。 strlen 我们先来看一个我们最熟悉的求字符串长度的库…

【Echart多场景示例应用】Echarts柱状图、折线图、饼图、雷达图等完整示例。 echarts主标题和副标题的位置、样式等设置(已解决附源码)

**【写在前面】**前端时间做一个echarts的页面调整,临时客户要求加一个参数(总容量)显示,当时我就想用个默认的副标题吧,哪知客户和我说得紧跟在主标题后面,于是乎我就根据设置做了一个调整,我也…

燕山大学-面向对象程序设计实验 - 实验1 C++基础

CSDN的各位uu们你们好,今天千泽燕山大学-面向对象程序设计实验 - 实验1 C基础 相关内容, 接下来让我们一起进入c的神奇小世界吧,相信看完你也能写出自己的实验报告!实验一 C基础 1.1 实验目的 1.了解并熟悉开发环境,学会调试程序; 2&#xf…

超过10000人学习的Fiddler抓包教程,只需一小时就可以精通!

如果还是有朋友不太明白的话,可以看看这套视频,有实战讲解 零基础玩转Fiddler抓包在测试领域应用实战!一、Fiddler与其他抓包工具的区别 1、Firebug虽然可以抓包,但是对于分析http请求的详细信息,不够强大。模拟http请…

【Linux】信号的产生、保存、捕捉处理 (四种信号产生、核心存储、用户态与内核态、信号集及其操作函数)

文章目录1、什么是信号?2、信号的产生2.1 通过键盘产生信号2.2 通过系统调用产生信号2.3 硬件异常产生的信号2.4 由软件条件产生的信号2.5 进程的核心转储3、信号的保存4、信号的捕捉4.1 用户态和内核态4.2 用户态到内核态的切换4.3 信号捕捉过程5、信号集操作函数以…

Spring——Spring整合Mybatis(XML和注解两种方式)

框架整合spring的目的:把该框架常用的工具对象交给spring管理,要用时从IOC容器中取mybatis对象。 在spring中应该管理的对象是sqlsessionfactory对象,工厂只允许被创建一次,所以需要创建一个工具类,把创建工厂的代码放在里面&…

Qt不会操作?Qt原理不知道? | Qt详细讲解

文章目录Qt界面开发必备知识UI界面与控件类型介绍Qt设计器原理控件类型的介绍信号与槽机制处理常用控件创建与设置常见展示型控件创建与设置常见动作型控件创建与设置常见输入型控件创建与设置常见列表控件创建于设置Qt中对象树的介绍项目源码结构刨析.pro.hmain.cpp.cppQt界面…

JVM的几种GC

GC JVM在进行GC时,并不是对这三个区域统一回收。大部分时候,回收都是新生代~ 新生代GC(minor GC): 指发生在新生代的垃圾回收动作,因为Java对象大多都具备朝生夕灭的特点,所以minor GC发生得非…

【问题排查】Linux虚拟机无法识别串口与ttyUSB

虚拟机串口连接失败问题 小哥的Linux系统是用虚拟机来装的,最近恰好需要用到串口和Linux进行通信,连接好硬件之后,发现虚拟机上找不到串口。 经查询才发现通过虚拟机启动的系统,正常情况下是无法使用串口进行通信的,需…

Ast2500增加用户自定义功能

备注:这里使用的AMI的开发环境MegaRAC进行AST2500软件开发,并非openlinux版本。1、添加上电后自动执行的任务在PDKAccess.c中列出了系统启动过程中的所有任务,若需要添加功能,在相应的任务中添加自定义线程。一般在两个任务里面添…

隐私计算将改变金融行业的游戏规则?

开放隐私计算 01背景2月底,相关部门印发《数字中国建设整体布局规划》提出,到2025年,基本形成横向打通、纵向贯通、协调有力的一体化推进格局,数字中国建设取得重要进展;到2035年,数字化发展水平进入世界前…

前端安全(自留)

目录XSS——跨站脚本常见解决CSRF ——跨站请求伪造常见解决XSS——跨站脚本 当目标站点在渲染html的过程中,遇到陌生的脚本指令执行。 攻击者通过在网站注入恶意脚本,使之在用户的浏览器上运行,从而盗取用户的信息如 cookie 等。 常见 解…

机械学习 - scikit-learn - 数据预处理 - 2

目录关于 scikit-learn 实现规范化的方法详解一、fit_transform 方法1. 最大最小归一化手动化与自动化代码对比演示 1:2. 均值归一化手动化代码演示:3. 小数定标归一化手动化代码演示:4. 零-均值标准化(均值移除)手动与自动化代码演示&#x…

优秀开源软件的类,都是怎么命名的?

日常编码中,代码的命名是个大的学问。能快速的看懂开源软件的代码结构和意图,也是一项必备的能力。 Java项目的代码结构,能够体现它的设计理念。Java采用长命名的方式来规范类的命名,能够自己表达它的主要意图。配合高级的 IDEA&…

什么是谐波

什么是谐波 目录 1. 问题的提出 2. “谐”字在中英文中的原意 2.1 “谐”字在汉语中的原义 2.2 “谐”字对应的英语词的原义 3.“harmonics(谐波)”概念是谁引入物理学中的? 4.“harmonics(谐波)”的数学解释 1. 问题的提出 “谐波”这个术语用于各种学科&am…