【计算机网络】TCP协议

文章目录

  • TCP协议
    • TCP的结构
    • TCP的特点
  • TCP如何保证可靠传输
    • 确认应答(可靠机制)
    • 超时重传(可靠机制)
    • 连接管理(可靠机制)
    • 滑动窗口(效率机制)
    • 流量控制(可靠机制)
    • 拥塞控制(可靠机制)
    • 延时应答(效率机制)
    • 捎带应答(效率机制)
  • 面向字节流
  • 异常处理
    • 进程崩溃
    • 主机关机(正常情况)
    • 主机掉电(非正常情况)
    • 网线断开

TCP协议

TCP的结构

在这里插入图片描述

源端口号和目的端口号就是说数据从哪里来到哪里去。

4位首部长度:TCP报头的长度是不固定的报头最短是20字节(没有选项),报头最长是60字节(选项最多是40字节)。

校验和:和UDP协议一样。

保留位:因为UDP的长度是64kb,我们无法改变,所以发明TCP的人做出了改变,加入了保留位,先占个位置,如果后面需要就可以进行扩展使用。

TCP的特点

1.有连接:发送方和接收方会保留对方的信息(如果A和B建立连接,B拒绝了,就无法建立连接,通信就无法完成)

2.可靠传输:A给B发消息,消息有没有成功送达A可以感知到(如果发送失败就可以进行采取一定的措施)

3.面向字节流:TCP的传输和文件操作一样都是以字节为单位的

4.全双工:一个通道允许双向通信就是全双工反之就是半双工(一个socket对象既可以发送数据也能接收数据)

TCP的核心就是可靠传输

TCP如何保证可靠传输

确认应答(可靠机制)

发送方把数据发送给接收方后,接收方收到数据之后就会给发送方返回一个应答报文(acknowledge 简称ack),发送方收到应答报文后就知道自己的数据发送成功了。
在这里插入图片描述

每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据,下一次你从哪里开始发。

在这里插入图片描述

如何确认一个数据包是普通数据还是ack数据呢?

上面的TCP结构图中ACK为1,就表示当前数据包是一个应答报文,此时该数据包中的确认序号字段才能生效,如果这一位为0,则表示当前数据包是一个普通报文,此时该数据包中的确认序号字段不会生效。

通过特殊的ack数据包里携带的确认序号告诉发送方哪些数据已经被收到了,此时发送方就知道自己刚刚发送的数据是否成功。TCP的初心就是可靠传输,达成可靠传输的核心机制是确认应答

超时重传(可靠机制)

A发送数据给B后,可能因为网络拥堵等原因,数据无法到达B;如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发。但是,主机A未收到B发来的确认应答,也可能是因为ACK丢失了。

确认应答是一个比较理想的情况,如果网络传输过程中,出现了丢包该怎么办?

首先我们要知道丢包的原因:

如果我们把网络想象成错综复杂的公路,在公路上就会有很多收费站,正常情况如果车流量不大,车辆都能正常通过,但是如果节假日就会发生堵车的情况,这种情况车辆就没办法正常通过。在网络中我们可以把收费站理解成 “路由器/交换机” 如果数据包太多,就会在路由器/交换机中出现 “堵车” 的情况,但是路由器/交换机针对 “堵车” 的情况是比较粗暴的,它会把数据包直接丢掉,此时这个数据包就在网络上消失了。这也就是我们所说的丢包。

丢包是一个随机事件,因此在TCP传输过程中存在两种情况:
在这里插入图片描述

无论是哪一种情况,A都会重新传输,如果丢包的概率是10%,再重传一次,两次都丢包的概率就是1%,传输成功的概率是很大的,重传操作大幅度提升了数据传输成功率。

那么发送方何时进行重传呢?

发送方,发出数据后,会等待一段时间,如果这个时间内没有收到ack就会触发重传。

初始的等待时间是可以配置的,也可以动态变化,每经历一次超时重传,下次的等待时间就会变长。但是也不是无限变长,超时重传若干次后就会触发TCP的重置连接。

如果传输的时候ack丢了,触发了超时重传,那么接收方收到了两条一样的数据这样会不会给带来bug呢?

TCP有一个接收缓冲区(一个内存空间)会保留已经收到的数据和数据的序号,接收方如果发现,当前发送方发来的数据是已经在接收缓冲区中,接收方就会直接把这个后来的的数据丢弃掉,以确保读的时候只读到一条数据。

接收缓冲区不仅可以去重,还能进行重新排序,确保发送的顺序。

连接管理(可靠机制)

连接管理:建立连接(TCP三次握手)+ 断开连接(TCP四次挥手)

TCP三次握手:TCP在连接过程中,通信双方一共需要 “打三次招呼” 才能建立连接。
在这里插入图片描述

三次握手的核心作用

1.确认当前网络是否通畅

2.让发送方和接收方都知道知道的接收能力和发送能力是否正常

3.让双方在握手过程中针对一些重要的参数进行协商

TCP四次挥手:断开连接(客户端和服务器都可以发起)
在这里插入图片描述

TCP四次挥手可以把中间的两次合二为一吗?

不一定

不能合并的原因是ack和第二个fin触发的时机不同,ack是内核响应的(B收到fin会立即返回ack),而第二个fin是应用程序的代码触发的,从服务器收到fin(同时返回ack)再到执行到发起fin的代码,这中间要经历的时间是不确定的。

TCP三次挥手的ack和第二个syn都是内核触发的,同一时机,所以可以合并。

滑动窗口(效率机制)

因为TCP的可靠传输会影响传输的效率(多出了一些等待ack的时间,单位时间内能传输的数据就少了),滑动窗口就是让可靠传输对性能的影响少一些。TCP只要引入了可靠性,传输的效率是不可能超过没有可靠性的UDP的。TCP这里的效率机制是为了缩短和UDP之间的差距。

那么TCP是如何提升效率的呢?
在这里插入图片描述

窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。上图的窗口大小就是4000个字节(四个段)。发送前四个段的时候,不需要等待任何ACK,直接发送;收到第一个ACK后,滑动窗口向后移动,继续发送第五个段的数据;依次类推;操作系统内核为了维护这个滑动窗口,需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答;只有确认应答过的数据,才能从缓冲区删掉;窗口越大,则网络的吞吐率就越高。

在这里插入图片描述

如果传输过程中出现丢包怎么办呢?
在这里插入图片描述

如果通信双方传输的数据量比较小,也不频繁,就任然是普通的确认应答和超时重传,如果通信双方传输的数据量比较大,也比较频繁,此时就会进入滑动窗口模式,按照快速重传的方式处理。

通过滑动窗口的方式传输数据,效率会提升,窗口越大,传输效率越高(一段时间等待的ack多了,总的等待时间就少了)

但是滑动窗口并不是越大越好,如果传输速度太快,接收方就可能会处理不过来,进而接收方就会出现丢包,TCP的前提是可靠传输,在可靠性的基础上再提高传输效率。

流量控制(可靠机制)

接收方处理数据的速度是有限的。如果发送方发的太快导致接收方的缓冲区占满,这个时候如果发送方继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。站在接收方的角度,反向制约发送方的发送速度。(发送方的发送速度不应该超过接收方的处理能力)TCP支持根据接收方的处理能力,来决定发送方的发送速度,这个机制就叫做流量控制

在这里插入图片描述

拥塞控制(可靠机制)

虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的。TCP引入 慢启动 机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据。

流量控制是考虑接收方的处理能力,拥塞控制是考虑通信过程中中间节点的情况。

由于中间节点结构复杂难以进行量化,所以我们可以使用 “ 实验” 来找到一个合适的值。

比如,先让A按照比较低的速度先发送数据,如果传输顺利没有丢包,就再尝试更大的窗口大小来发送数据,随着窗口的大小增大,达到一定程度,中间节点可能会出现问题,此时这个节点就可能会出现丢包,,A发现丢包了,就会重新调整窗口大小,如果发现还是丢包,就会继续缩小窗口大小,如果不丢包就尝试增大窗口大小。在这个过程中,发送方不停的调整窗口大小,逐渐达到“动态平衡” 这种做法,相当于是把中间节点都视为“整体” 通过实验的方式找到中间节点的瓶颈。

在这里插入图片描述

少量的丢包,我们仅仅是触发超时重传。大量的丢包,我们就认为网络拥塞。当TCP通信开始后,网络吞吐量会逐渐上升。随着网络发生拥堵,吞吐量会立刻下降。拥塞控制,归根结底是TCP协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力的折中方案。

延时应答(效率机制)

A把数据传输给B,B就会立即返回ACK给A(正常情况)

A把数据传输给B,B不会立即返回ACK给A(延时应答)

延时应答本质上是为了提升传输效率,发送方的窗口大小就是传输效率的关键,流量控制是根据接收缓冲区的剩余空间来决定发送速度的,如果有办法让流量控制的窗口大小更大,发送速度更快(前提是接收方能处理过来),延时返回ack给接收方更多的时间来读取缓冲区的数据,读取缓冲区的数据之后,缓冲区的剩余空间就更大了,返回的窗口大小就更大了,传输效率就提高了。

比如说,初始情况下,接收缓冲区剩余空间是10kb,如果立即返回ack那么返回的窗口大小是10kb,如果延时一段时间返回ack,在这个过程中读取了2kb,那么此时返回的窗口大小就是12kb。

窗口越大,网络吞吐量就越大,传输效率就越高。我们的目标是在保证网络不拥塞的情况下尽量提高传输效率。

捎带应答(效率机制)

捎带应答是在延时应答的基础上又进行了效率提升,在网络通信中往往是 “一问一答”这样的通信模式。
在这里插入图片描述

面向字节流

当同时有多个应用层数据包被传输过去的时候就有可能出现粘包问题
在这里插入图片描述

那么我们如何解决粘包问题呢?

核心思路:明确应用层数据包之间的边界,①引入分隔符 ②引入长度
在这里插入图片描述

异常处理

进程崩溃

进程没了,程序异常终止,文件描述符表也就释放了,相当于是调用了socket.close(),此时会触发FIN,对方收到之后自然就会返回FIN和ACK(正常的四次挥手断开连接)TCP的连接可以独立于进程存在(进程没来,TCP连接不一定断开)

主机关机(正常情况)

进行关机的时候,就会先触发强制终止进程操作(相当于进程崩溃)此时就会触发FIN,对方收到之后自然就会返回FIN和ACK,不仅仅是进程没了,整个系统也可能会关闭,如果在系统关闭之前对端返回的FIN和ACK到了,此时系统还是可以返回ACK的,进行正常的四次挥手,如果系统已经关闭,FIN和ACK没收到,就无法进行后续的ACK响应了,站在对端的角度,对端会以为是自己的FIN丢包了,就会重传FIN,重传几次没有响应就会放弃连接(此时会删除对端的信息)

主机掉电(非正常情况)

主机掉电是一瞬间的事情,来不及杀进程,也来不及发送FIN,主机就直接停机了,对端不一定知道这件事。

①如果对端是在发送数据(接收方掉电),发送的数据就会一直等待ACK,触发超时重传,触发TCP的重置连接功能,会发起 “复位报文段”(TCP结构中的RST)

②如果对端是在接收数据(发送方掉电)对端还在等待数据到达,等了很久没有消息,此时是无法区分对端是没有发送消息还是对方出问题了(挂了)此时接收方也会周期性的给对方发起一个特殊的不携带业务数据的数据包,如果对方没有应答,重复了多次后任然没有响应,此时就会视为对方挂了,就会单方面释放连接。

网线断开

网线断开和主机掉电相似。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

场景图形管理-多视图多窗口渲染示例(4)

多视图多窗口渲染示例的代码如程序清单8-6所示 // 多视图多窗口渲染示例 void compositeViewer_8_6(const string &strDataFolder) {// 创建一个CompositeViewer对象osg::ref_ptr<osgViewer::CompositeViewer> viewer new osgViewer::CompositeViewer();// 创建两个…

vue源码分析(八)—— update分析(首次渲染)

文章目录 前言一、update首次渲染的核心方法__path__二、__path__方法详解1. 文件路径2. inBrowser的解析&#xff08;1&#xff09;noop 的空函数定义&#xff1a;&#xff08;2&#xff09;patch 的含义 3. createPatchFunction 的解析4. path 方法解析&#xff08;1&#xf…

基于JavaWeb+SpringBoot+Vue医疗器械商城微信小程序系统的设计和实现

基于JavaWebSpringBootVue医疗器械商城微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 摘 要 目前医疗器械行业作为医药行业的一个分支&#xff0c;发展十分迅速。…

μC/OS-II---消息邮箱管理2(os_mbox.c)

目录 消息邮箱发送&#xff08;扩展&#xff09;从消息邮箱获取/无等待消息邮箱状态查询消息邮箱中断等待用邮箱作为二值信号量&#xff08;无&#xff09;用邮箱实现延时&#xff08;无&#xff09; 消息邮箱发送&#xff08;扩展&#xff09; #if OS_MBOX_POST_OPT_EN > …

私域电商:实体商家想通过异业联盟引流,应该怎么做?

​异业联盟引流是一种有效的营销策略&#xff0c;通过与不同行业的企业或品牌合作&#xff0c;共同推广产品或服务&#xff0c;扩大品牌影响力和用户群体。以下是异业联盟引流的一些详细过程&#xff1a; ​选择合作联盟&#xff1a; 首先&#xff0c;需要选择与自己企业或品…

C#创建并调用dll

文章目录 1.VS2019创建C#主程序2.编译主程序3.添加类库工程&#xff0c;并添加计算逻辑4.给主程序添加引用项5.重新编译主程序6.主程序添加测试逻辑 1.VS2019创建C#主程序 2.编译主程序 debug目录下生成exe&#xff1a; 3.添加类库工程&#xff0c;并添加计算逻辑 添加计算逻…

应用层使用select进行检测连接状态

可以参考TCP连接保活机制来设计应用层的连接状态监测&#xff0c;同时需要注意到有两个关键点&#xff1a; 1.需要使用定时器&#xff0c;这可以通过使用 I/O 复用自身的机制来实现&#xff0c;这点可以先看一下《使用select实现定时任务》&#xff1b; 2.需要设计一个 PING-PO…

alias linux 命令别名使用

如果在系统中你想要快速的完成一个命令&#xff0c;你可以使用alias命令&#xff1a; 如&#xff1a; alias ppsystemctl status httpd输入pp命令后即可得到如下结果 但这之时临时生效&#xff0c;一旦重启机器&#xff0c;命令就会失效&#xff1b;想要永久生效&#xff0c;…

vue-admin-template

修改登录接口 1.f12查看请求接口 模仿返回数据写接口 修改方式1 1.在env.devolopment修改 修改方式2 vue.config.js 改成本地接口地址 配置转发 后端创建相应接口&#xff0c;使用map返回相同的数据 修改前端请求路径 修改前端返回状态码 utils里面的request.js

成功解决:com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl.

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 前言 使用Spring 整合 mybatis的时候 报错…

ES5中实现继承

本篇文章主要说明在ES5中最通用最兼容的继承实现方式&#xff0c;继承作为面向对象的三大特性之一&#xff0c;在js中实现继承对代码的简洁性&#xff0c;逻辑的连贯性都有很大的帮助。 实现思路 封装创建中间联系对象的函数 继承可以简单理解为建立子类和父类之间的联系&…

Django测试环境搭建及ORM查询(创建外键|跨表查询|双下划线查询 )

文章目录 一、表查询数据准备及测试环境搭建模型层前期准备测试环境搭建代码演示 二、ORM操作相关方法三、ORM常见的查询关键字四、ORM底层SQL语句五、双下划线查询数据查询&#xff08;双下划线&#xff09;双下划线小训练Django ORM __双下划线细解 六、ORM外键字段创建基础表…

【408】计算机学科专业基础 - 操作系统

一、计算机系统概述 1.简介 什么是操作系统&#xff1f; 操作系统&#xff08;Operating Ststem&#xff0c; OS&#xff09;是指控制和管理整个计算机系统的硬件和软件资源&#xff0c;并合理地组织调度计算机的工作和资源的分配&#xff0c;以提供给用户和其他软件方便的接口…

AI中文版怎么用,版本分享,GPT官网入口

网页版上线啦&#xff0c;在线助力大学生、上班族的高效生活&#xff01; GPT4.0是OpenAI最新推出的聊天模型&#xff0c;它的语言理解和生成能力比以前的版本更强大。对于忙碌的上班族来说&#xff0c;GPT4.0能帮助你高效处理工作中的大部分写作任务&#xff0c;比如撰写报告…

【搭建统一的IOS开发环境,Ruby链之CocoaPods】

CocoaPods 前提HomebrewHomebrew是什么&#xff1f;Homebrew怎么安装?Homebrew怎么用?有哪些必须知道的命令Homebrew和CocoaPods的关系卸载Homebrew RubyrbenvRubyGems 和 Bundler安装Ruby管理Ruby更新Ruby替换Ruby镜像方式1方式2 CocoaPods安装CocoaPodsCocoaPods使用安装的…

嵌入式养成计划-53----ARM--串口通信

一百三十四、串口通信 134.1 串口的概念 串口&#xff08;UART&#xff09;&#xff1a;Universal asynchronous receiver transmitter (USART/UART)&#xff0c;通用异步接收发送器通过串口可以实现两个不同机器之间的信息交互串口通信属于总线通信的一种 134.2 总线的概念…

基于C#实现猴子偷桃

猴子第一天摘下若干个桃子&#xff0c;当即吃了一半&#xff0c;还不过瘾就多吃了一个。第二天早上又将剩下的桃子吃了一半&#xff0c;还是不过瘾又多吃了一个。以后每天都吃前一天剩下的一半再加一个。到第 10 天刚好剩一个。问猴子第一天摘了多少个桃子&#xff1f; 分析: 这…

11.16 知识总结(模型层更多内容)

一、 多表查询&#xff08;跨表查询&#xff09; <br class"Apple-interchange-newline"><div></div> 子查询&#xff1a;分步查询 链表查询&#xff1a;把多个有关系的表拼接成一个大表(虚拟表) inner join left join right join 1.1 基于双下划…

电脑版微信图片保存在哪个文件夹,如何一次性全选保存

8-7 电脑版的微信聊天&#xff0c;接收到图片后&#xff0c;会保存到微信的个人数据文件夹中&#xff0c;但是有个问题是这些图片都是加密保存的&#xff0c;普通情况下&#xff0c;确实无法人工去取出来&#xff0c;但是下面有方法可以快速将这些图片在脱离微信的情况下&…

盲目跟风考PMP认证?PMP还剩多少含金量?

pmp含金量在如今&#xff0c;含金量还是不错的&#xff0c;但是也不要盲目跟风考&#xff0c;要确定它对你有用&#xff0c;你也会使用它。 什么人适合考PMP? 1、有项目管理实践经验&#xff1a;PMP是基于项目管理实践经验的认证考试&#xff0c;因此有项目管理实践经验的人…