TCP协议(建议收藏)

1. TCP特点

  1. 有连接:需要双方建立连接才能通信,在socket编程中服务端new ServerSocket(port)需要绑定端口,在客服端new Socket(serverIp, serverPort)与服务端建立连接
  2. 可靠传输:确认应答机制,超时重传机制
  3. 面向字节流:传输单位是字节
  4. 全双工:双向通信类似双行道

2. TCP的报文格式

image.png

  1. 源端口,目的端口:TCP的核心
  2. 32位序号,32位确认序号:确认应答机制中引入序号,防止后发先至的情况,32位序号针对请求数据进行编号,32位确认序号只针对ACK报文有效
  3. 选项:该部分可有可无,可以有以个选项也可以多个选项,选项可以是0个字节,最多40个字节
  4. 4位首部长度:描述TCP报头长度,单位是4字节,那就意味着报头长度最大是60字节(1111就是15*4=60)
  5. 保留位:现在没用,先占个位置
  6. 16位窗口大小:滑动窗口的大小,16位并不是说窗口最大是64kb,选项中有窗口大小的扩展因子,可以表示更大的窗口
  7. 16位校验和:校验发送和接收的时候数据是否一致

如果是第一次学可能会看懵掉,没关系,把下面内容看完再来看报文格式你就会很通透

3. 确认应答机制

image.png
当男生看到女生的回复后,就说明男生发的信息已经成功到达了,如果没有收到回复就可以认为上次发的数据丢失了。这就是确认应答机制,女生回复的“好的好的”就是应答报文ack。
image.png普通报文,ack为0;应答报文,ack为1

确认应答机制是TCP保证可靠性的最核心机制

当发送多条信息时可能出现下面情况:
image.png
此时女生后发的信息,男生先收到,让男生误以为女生答应了做他女朋友的请求,这是由于网络情况很复杂,很有可能“后发先至”。
解决方案就是对请求和返回的信息进行编号。
image.png
TCP是字节流协议,编号的时候,也是以字节为单位
image.png
image.png

4. 超时重传

当数据在传输过程中可能会发生丢包,因为网络环境很复杂,中间要经过很多路由器/交换机,某个交换机不但要传输我的数据还要传输别人的数据报,有很多很多数据报都要经过这个交换机,而交换机转发的能力是有上限的,很多数据报都经过该交换机,就会达到交换机的转发上限,就有可能导致有一部分数据报超时了。(类似于堵车)
当数据丢包的时候就要进行“超时重传”,丢包有两种情况一种是数据丢包,一种是应答报文丢了

  1. 数据丢包

image.png
当男生等了一段时间没收到女生的回应后,男生又在发了一次。这就是超时重传
第一次发生丢包时,发送方就会在达到超时时间的阈值之后,进行重传。如果重传的数据仍然没响应,就会继续重传,但是第二次超时的时间比第二次长,超时时间是逐渐变大的(假设一次丢包的概率10%,那两次都丢包的概率就是1%,说明网络情况比较差,后序在重传大概率也无法成功,不如降低传输频率,节省点主机开销)。如果重传几次后,仍然无法传输,就会尝试重置TCP连接(断开重连),如果还是连不上,就会释放连接。

  1. ack丢包

站在发送者的角度看,只知道没收到ACK,无法区分是发的数据丢了还是ACK丢了,因此发送者都会重传。如果是ACK丢包,发送者又重传就会导致接收方收到两份相同的数据,所以TCP会对相同的信息进行去重(根据序号进行去重)

5. 连接管理

TCP的连接是逻辑上虚拟连接,主机A和主机B建立连接,主机A的系统内核里有一个数据结构,包含了和他连接的是谁(IP,端口,使用的协议);主机B的内核的一个数据结构也记录了和他连接的谁(IP,端口,使用的协议)

5.1 三次握手

image.png
A发送syn尝试和B建立连接,主机B的内核立即返回ack接收对方的连接,内核同时也发送syn尝试和主机A建立连接,主机A返回ack接收对方的连接。建立连接的过程有四次数据交互过程,只不过主机B返回的ack和syn都是内核同时立即发送的,所以看起来就是三次的。

三次握手的意义

  1. 投石问路,检查当前网络情况是否通畅,这个期间并不传输任何业务数据
  2. 检查通信双方发送能力和接收能力是否正常,比如我约妹子打游戏

image.png
所以握手必须握三次才能够测试完整

  1. 协商一些重要的参数

例如TCP的序号并不是从1开始的,通常都是建立连接的时候协商一个数字,目的是保证两次连接的序号有差别,如果连接断开又快速重连,接收方就可以区分当前收到的数据是当前连接的还是上一个连接的。

两个重要的TCP状态

  1. LISTEN:服务器启动,绑定端口之后(new ServerSocket完成),服务器良好,可以让客服端连接(类似手机信号良好,可以让别人打电话给我)
  2. ESTABLISHED:连接建立好之后的稳定状态(类似于电话拨通,可以说话了)
5.2 四次挥手

通信双方,各自向对方申请断开连接,再各自给对方回应
image.png

四次挥手在某些情况下也会变成三次:TCP的捎带应答机制,会让ACK晚点发送,有可能和FIN(结束报文端)一起发送

两个重要的TCP状态
image.png

6. 滑动窗口

image.png
在没有引入滑动窗口之前是一问一答,主机A大量的时间都消耗在等待ACK上。因此提高效率的方法就是不等ACK,直接发送下一条数据。当然这里说的不等也不是完全不等而是每次批量发送一波数据,然后再等一波ACK,再发一波数据。这里不需要等待直接发送的数据的量,就称为“窗口大小”
image.png
批量发送4条数据,批量等待4条ACK,此时窗口大小就是4000字节。注意:主机A收到一条ACK就继续发一条数据,而不是等所有的ACK都到了,才统一发下一组。
image.png
发生一整波数据如果出现丢包/乱序时怎么办?

  1. 响应ACK丢了

image.png
这里的1001表示小于1001的数据都收到了,2001表示小于2001的数据都收到了,所以即使返回1001这个ACK丢了,下一次返回的2001就说明1-2000的数据已经收到了,包括了第一次的数据。这就类似于别人问你现在是高几呀?你说我已经大二了。
因此ACK丢包不需要任何处理

  1. 数据报丢了

image.png
在上面的过程中只是把丢的包进行了重传,没丢的包,没有重传,效率比较高,因此被称为“快速重传”(搭配滑动窗口机制的超时重传)

有了快速重传,超时重传还有意义吗?

在传输数据量很多,批量传输时自然是遵守快速重传的方式,如果传输的数据很少,此时仍然是按照超时重传的方式进行。在滑动窗口中如果是最后一个包丢了就是按照超时重传的方式。

窗口越大发送的速度越快,那窗口可以无限大吗?

发送的速度快了但是接收方的处理速度跟不上就会导致接收方丢弃一部分数据,而TCP需要保证可靠性的,TCP就要重传这些数据,这就导致了恶性循环。

7. 流量控制

在滑动窗口的基础上对发送速率做出限制的机制,根据接收方的接收能力,来反向影响发送方的发送速率。
接收方的接收速率如何衡量?

接收方使用接收缓冲区的剩余空间大小,来作为发送方发送速率(窗口大小)的参考数值

image.png
主机B收到的数据,就会先放到系统内核的接收缓冲区中,所谓缓冲区就是一个内存空间(字节数组)等待B这边的应用程序,通过Socket把数据从接收缓冲区中读取走。这就类似于生产者消费者模型A是生产者,往B的接收缓冲区生产数据,B的应用程序,从缓冲区中消费数据。
接收方B收到A的数据后,就会在ACK应答报文中,把当前接收缓冲区的剩余空间大小的值,反馈给发送方。
image.png

8. 拥塞控制

流量控制是通过接收方的接收速率,接收缓冲区剩余空间大小来衡量发送方的速率。在网络中不仅要考虑接收方还要考虑中间转发节点的情况。
如何衡量中间节点的情况?

把中间设备视为一个整体,通过实验来验证发送速度多少合适。开始的时候,发的慢一点,如果网络通畅就提高速度,提高到一定程度,发生丢包了,就再降低速度;速度降低后,发现又通畅了,就再提高速度。

image.png

9. 延迟应答

基于流量控制,引入的提高效率的机制,尽量让返回的接收缓冲区空间大一些,这样滑动窗口也就大一些,效率提高了。
image.png
image.png

10. 捎带应答

基于延时应答的基础上引入的
在4次挥手中说过,在某些情况下由于捎带应答机制可以变成3次
image.pngimage.png
TCP中只要把数据传输过去,对方收到之后,就会立即由内核返回一个ack报文,响应数据则是在应用程序中负责传输。由于这两操作是不同时机传输的,因此不能合并在一起,但是延时应答机制让这成为了可能。ACK原本是要立即返回的,但是由于延迟应答,稍等一会才返回,在某些情况下业务也正好在这个时候返回响应,此时就可以把这两个报文,合二为一了。

11. 面向字节流

面向字节流中存在一个典型问题“粘包问题”,举个例子
image.png
解决方案

要想解决粘包问题就要在应用层协议进行区分,只要定义应用层数据协议的时候,明确包和包之间的边界即可
1.通过分隔符,比如约定使用 ; 作为包结束的标记
2.指定包的长度,比如在数据包的开头位置声明长度

自定义应用层协议的几个典型实现,像xml,json,http这些都解决了粘包问题

12. TCP的异常处理

  1. 程序崩溃

进程异常退出,操作系统会回收进程资源,包括释放文件描述符表,这样的释放操作就相当于调用了对应的socket的close方法,执行close就会触发FIN结束报文,进一步进行四次挥手。

  1. 正常关机

关机的时候,系统会强制结束所有用户进程,和上述的进程崩溃类似。系统内核会进行文件描述符表的释放操作,进一步进行四次挥手

  1. 主机掉电
    1. 掉电的是接收方

此时发送方不知道对方挂了,继续发送数据,没有收到ACK,发送方就会触发超时重传,重传几次还没有应答就会尝试重置连接,失败后就会断开连接。

  1. 掉电的是发送方

接收方等了一段时间后,就会发送一个“心跳包”(心跳包是周期性触发的,只是一个简单的不携带任何业务数据的包)存在的意义就是确认一下对方是否存在,如果对方不返回心跳包就说明对方挂了,此时就放弃连接了。

  1. 网线断开

情况和主机掉电一样,只不过通信双方主机是正常的,通信双方各自按照上述的两种情况进行
13. 常见面试题
如何将UDP实现为可靠传输?
基于UDP的应用层实现确认应答机制,引入序列号,超时重传机制。

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

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

相关文章

【文末送JAVA书】包头开发发展

【点我-这里送书】 本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的…

jbase支持连IRIS

jbase设计的时候就抽取了IDbFactory接口,支持不同数据库只要配置该接口实现类即可,那么就用IRIS测试下多数据库支持。 首先从IRIS安装目录拷贝jar包 然后实现数据库驱动接口 package LIS.Dal.Base;import LIS.Core.MultiPlatform.LISConfigurtaion;…

Java基础(第六期):Java基础巩固、逢七跳过、数组求和、判断数组是否相等、数组逆置、元素位置查找、评委打分、随机产生验证码

Java基础专栏【点击跳转学习】 Java基础(第六期):对前五期的综合练习 文章目录 综合练习巩固JAVA基础第六期一、逢 7 跳过二、数组元素求和三、判断两个数组元素是否相同四、查找元素在数组中的索引五、数组元素反转使用for循环的实现方式一、…

MySQL中的索引

目录 一、概念 二、作用和特点 作用 特点 三、使用场景 四、使用 1、查看索引 2、创建索引 3、删除索引 五、索引底层数据结构的实现 B树(B-树) B树 特点 重复出现的好处 一、概念 索引 翻译成英文:index(下标&#xf…

Doris学习--1、Doris简介、操作Doris、Doris架构(数据模型)

星光下的赶路人star的个人主页 心之所向,剑之所往 文章目录 1、Doris简介1.1 快速开始1.2 安装配置1.2.1 应知前提1.2.2 配置Doris1.2.2.0 配置前提1.2.2.1 配置FE(Frontend)1.2.2.2 启动FE1.2.2.3 连接FE1.2.2.4 停止FE1.2.2.5 配置BE&#…

InSAR形变监测方法与研究进展(朱建军,中南大学)

文章目录 摘要引言InSARInSAR原理SAR卫星 InSAR监测技术D-InSARMT-InSARPS-InSARSBAS-InSARDS-InSAR(Distributed Scatterer InSAR)MAI(Multi-Aperture InSAR, 多孔径InSAR) InSAR形变监测应用与发展城市沉降监测矿山形变监测地震…

深度探究深度学习常见数据类型INT8 FP32 FP16的区别即优缺点

定点和浮点都是数值的表示(representation),它们区别在于,将整数(integer)部分和小数(fractional)部分分开的点,点在哪里。定点保留特定位数整数和小数,而浮点…

SpringBoot学习(黑马程序员day12)

1jwt令牌 JWT的组成: (JWT令牌由三个部分组成,三个部分之间使用英文的点来分割) 第一部分:Header(头), 记录令牌类型、签名算法等。 例如: {"alg":"HS256",&qu…

【已解决】ModuleNotFoundError: No module named ‘matplotlib‘

问题描述 Traceback (most recent call last): File "/home/visionx/nickle/temp/SimCLR/linear_evaluation.py", line 207, in <module> import matplotlib.pyplot as plt ModuleNotFoundError: No module named matplotlib 解决办法 pip install matp…

嵌入式软件开发是个啥职业?

在硬件行业中&#xff0c;有一类工作岗位是更偏向软件的&#xff0c;或者说是软硬结合非常紧密的工作&#xff0c;那就是嵌入式开发工程师。 说起嵌入式&#xff0c;可能很多没有接触过电子类的人没有听说这些东西。 其实简单来说&#xff0c;嵌入式开发就是写程序去控制硬件电…

HBuilderX vue项目打包上传到服务器

完成后有个’dist’目录,把真个目录通过FTP 上传到服务器,Mac电脑使用cyberduck 上传 服务器使用‘宝塔’进行一件部署,基本上就是傻瓜式的点击下一步

MySQL数据库实验记录

输入密码 显示数据库 mysql命令以分号;结束 创建数据库 建表 写错了就会报错 没选数据库也会报错

十五、信号量

1、概述 (1)前面介绍的队列(queue)可以用于传输数据&#xff1a;在任务之间、任务和中断之间。 (2)有些时候我们只需要传递状态&#xff0c;并不需要传递具体的信息&#xff0c;比如&#xff1a; 我的事做完了&#xff0c;通知一下你。卖包子了、卖包子了&#xff0c;做好了…

软件过程模型分析与适应场景: 瀑布、原型、增量、螺旋、组件化和统一模型简介

软件过程模型&#xff1a; 瀑布模型 ​ 有很强的前后关联性&#xff0c;前一阶段的输出是后一阶段的输入&#xff0c;而且不可回溯性。 适应场景&#xff1a; ​ 软件开发人员经验丰富​ 需求变化少&#xff0c;变更少&#xff0c;可以一次性获取全部需求​ 项目风险低&…

专用博客模板

【点我-这里送书】 本人详解 作者&#xff1a;王文峰&#xff0c;参加过 CSDN 2020年度博客之星&#xff0c;《Java王大师王天师》 公众号&#xff1a;JAVA开发王大师&#xff0c;专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生&#xff0c;期待你的…

Docker实用篇

Docker实用篇 0.学习目标 1.初识Docker 1.1.什么是Docker 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署…

六:ffmpe音频参数的使用

-aframes 设置要输出的音频帧数 -b:a 设置音频码率 -ar 设定采样率 -ac 设定声音的Channel数 -acodec 设定声音的编解码器&#xff0c;如果用copy标识原始编解码数据必须被copy -an 不处理音频 -af 音频过滤器 写笔记前查阅了其它说明&#xff0c; -aframes&#xff1a;等价…

海康威视嵌入式软件一面(技术面)

海康威视技术面试大部分都是基础问题和牛客上的问题&#xff0c;最后还有手撕代码部分也是牛客原题&#xff0c;总体中等偏难。 一、问答题 1.什么是野指针&#xff0c;野指针如何形成 【C语言基础】野指针与空指针_野指针和空指针-CSDN博客 2.const和static作用和区别 sta…