计算机网络八股文之TCP协议
TCP/IP模型
- 链路层
- 物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后再转化为1、0,也就是我们常说的数模转换与模数转换)。这一层的数据叫做比特。
- 数据链路层:在不可靠的物理介质上保证可靠的数据帧传输,这一层数据叫做数据帧。
- 网络层:在位于不同地理位置的网络中的两个主机系统之间提供连接和路径选择。实现点到点的传输。这一层的数据叫做数据报。
- 传输层:实现一个端口到另一个端口的数据段传输。实现端到端的传输。这一层的数据叫做数据段。
- 应用层:是最靠近用户的层。这一层为用户的应用程序(例如电子邮件、文件传输和终端仿真)提供网络服务。
MTU和MSS
- MTU最大传输单元。不同的层的MTU也是不同的,IP协议的数据报最大为65535个字节,所以当IP数据报大于MTU的时候就需要对数据进行分片,这也是IP协议的主要功能之一。
- TCP为了避免被发送方分片,它主动把数据分成小段再交给网络层。最大的分段大小称为MSS(Maximum Segment Size),它相当于把MTU刨去IP头和TCP头之后的大小,所以一个MSS恰好能装进一个MTU中。在三次握手的时候接收方和发送方都会声明自己MSS,因为接收方和发送方的MTU可能是不同的,最终会以较小的MSS为准。
- UDP协议没有MSS的概念,传输层的数据可能一股脑的交给网络层,所以数据可能会被分片而影响性能。
TCP
TCP的结构图
- 序号:Seq(Sequence Number)序号占32位,用来标识从计算机A发送到计算机B的数据包的序号,计算机发送数据时对此进行标记。
- 确认号:Ack(Acknowledge Number)确认号占32位,客户端和服务器端都可以发送,Ack = Seq + 1。
- 首部长度:占4位,表示4字节*首部长度,最大值为15,表示首部长60字节。
- 标志位:每个标志位占用1Bit,共有6个,分别为 URG、ACK、PSH、RST、SYN、FIN,具体含义如下:
-
- URG:紧急指针(urgent pointer)有效。
- ACK:确认序号有效。
- PSH:接收方应该尽快将这个报文交给应用层。
- RST:重置连接。
- SYN:建立一个新连接。
- FIN:断开一个连接。
TCP三次握手和四次挥手
三次握手
- SYN_SEND:客户端socket执行CONNECT连接,发送SYN包,进入此状态。
- SYN_RECV:服务端收到SYN包并发送服务端SYN包,进入此状态。
- ESTABLISH:表示连接建立。客户端发送了最后一个ACK包后进入此状态,服务端接收到ACK包后进入此状态。
四次挥手
- ESTABLISH:表示连接建立。客户端发送了最后一个ACK包后进入此状态,服务端接收到ACK包后进入此状态。
- FIN_WAIT_1:终止连接的一方(通常是客户机)发送了FIN报文后进入。等待对方FIN。
- CLOSE_WAIT:(假设服务器)接收到客户机FIN包之后等待关闭的阶段。在接收到对方的FIN包之后,自然是需要立即回复ACK包的,表示已经知道断开请求。但是本方是否立即断开连接(发送FIN包)取决于是否还有数据需要发送给客户端,若有,则在发送FIN包之前均为此状态。
- FIN_WAIT_2:此时是半连接状态,即有一方要求关闭连接,等待另一方关闭。客户端接收到服务器的ACK包,但并没有立即接收到服务端的FIN包,进入FIN_WAIT_2状态。
- LAST_ACK:服务端发动最后的FIN包,等待最后的客户端ACK响应,进入此状态。
- TIME_WAIT:客户端收到服务端的FIN包,并立即发出ACK包做最后的确认,在此之后的2MSL时间称为TIME_WAIT状态。
关于四次挥手中TIME_WAIT状态等待2MSL的原因
客户端发送最后的ACK报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:
- 确保最后一个确认报文能够到达。如果 B 没收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
- 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。
设置端口复用
在server的TCP连接没有完全断开之前不允许重新监听是不合理的。因为,TCP连接没有完全断开指的是connfd(127.0.0.1:6666)没有完全断开,而我们重新监听的是lis-tenfd(0.0.0.0:6666),虽然是占用同一个端口,但IP地址不同。解决这个问题的方法是使用setsockopt()设置socket描述符的选项SO_REUSEADDR为1,表示允许创建端口号相同但IP地址不同的多个socket描述符。在server代码的socket()和bind()调用之间插入如下代码:
int opt = 1; setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
为什么是三次握手,不是两次?不是四次?
三次握手的原因(相对两次和四次而言)
- 三次握手才可以避免建立多个连接(相对两次)
- 三次握手才可以同步双方的初始序列号,MSS,窗口大小等信息,两次握手最多建立一个单向的连接。
- 三次握手才可以避免资源浪费
- 相对于四次握手而言,减少了连接次数;相对于两次,避免了冗余连接
为什么不是两次?
- 无法防止历史连接的建立,会造成双方资源的浪费
- 无法可靠的同步双方序列号
为什么不是四次?
- 三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数(四次握手讲三次握手的第二步拆成了两步,没必要这样做)
TCP的流量控制
接收方为了避免分组丢失,控制发送者的发送速度,使得接收者来得及接收的一种流量控制方法。流量控制根本目的是防止分组丢失,它是构成TCP可靠性的一方面,由滑动窗口协议(连续ARQ协议)实现。滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制。主要的方式就是接收方返回的 ACK 中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送。
滑动窗口详解
TCP的拥塞控制
拥塞控制是发送方为了避免因为网络拥塞而导致分组丢失所采用的一种发送速率的控制方法。发送方需要根据网络拥塞情况维护一个叫做拥塞窗口(cwnd)的状态变量,控制当前的发送速率。
TCP 主要通过四个算法来进行拥塞控制:
- 慢开始
- 拥塞避免
- 快重传
- 快恢复
慢开始与拥塞避免
- 发送的最初执行慢开始,令 cwnd = 1,当收到确认后,将 cwnd 加倍,2、4、8 ...
- 设置一个慢开始门限 ssthresh,当 cwnd >= ssthresh 时,进入拥塞避免,每个轮次只将 cwnd 加 1。
- 如果出现了超时,则令 ssthresh = cwnd / 2,然后重新执行慢开始。
快重传与快恢复
- 在发送方,如果收到三个重复确认,此时执行快重传,立即重传下一个报文段。
- 执行快恢复,令 ssthresh = cwnd / 2 ,cwnd = ssthresh,注意到此时直接进入拥塞避免。
流量控制和拥塞控制的区别
- 流量控制属于通信双方协商;拥塞控制涉及通信链路全局。
- 流量控制需要通信双方各维护一个发送窗、一个接收窗,对任意一方,接收窗大小由自身 决定,发送窗大小由接收方响应的TCP报文段中窗口值确定
- 拥塞控制的拥塞窗口大小变 化由试探性发送一定数据量数据探查网络状况后而自适应调整。
- 实际最终发送窗口 = min{流控发送窗口,拥塞窗口}
TCP粘包、拆包以及解决办法
粘包/拆包
接收端只收到一个数据包,但是这一个数据包中包含了发送端发送的两个数据包的信息,这种现象即为粘包。(TCP包中数据的粘合!不是TCP包的粘合,TCP包通过首部能区分开)这种情况由于接收端不知道这两个数据包的界限,所以对于接收端来说很难处理。
接收端收到了两个数据包,但是这两个数据包要么是不完整的,要么就是多出来一块,这种情况即发生了拆包和粘包。这两种情况如果不加特殊处理,对于接收端同样是不好处理的。
为什么会发生 TCP 粘包、拆包?
- 发送的数据大于 TCP 发送缓冲区剩余空间大小,拆包。
- 发送数据大于 MSS(最大报文长度),拆包。
- 发送的数据小于 TCP 发送缓冲区的大小,TCP 将多次写入缓冲区的数据一次发送出去,粘包。
- 接收数据端的应用层没有及时读取接收缓冲区中的数据,粘包。
解决办法
由于 TCP 本身是面向字节流的,无法理解上层的业务数据,所以在底层是无法保证数据包不被拆分和重组的,这个问题只能通过上层的应用协议栈设计来解决,根据业界的主流协议的解决方案,归纳如下:
- 消息定长:发送端将每个数据包封装为固定长度(不够的可以通过补 0 填充),这样接收端每次接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。
- 设置消息边界:服务端从网络流中按消息边界分离出消息内容。在包尾增加回车换行符进行分割,例如 FTP 协议。
- 将消息分为消息头和消息体:消息头中包含表示消息总长度(或者消息体长度)的字段。
TCP心跳机制
tcp维护长连接,一般是在应用层引入心跳机制。就是每隔一段时间发一个探测包,看连接是否顺畅,来确定连接的可用性。
TCP如何实现可靠传输的?
- 序列号:保证按序交付
- 检验和:保证数据不出错
- 流量控制、拥塞控制:调控双方的发送速率,防止因为网络阻塞,缓冲区满等原因丢包
- ACK确认机制、超时重传:保证每一个字节段的交付。
UDP
UDP结构图
TCP和UDP对比
- 是否面向连接 :UDP 在传送数据之前不需要先建立连接。而 TCP 提供面向连接的服务,在传送数据之前必须先建立连接。
- 是否是可靠传输:远地主机在收到 UDP 报文后,不需要给出任何确认,并且不保证数据不丢失,不保证是否顺序到达。TCP 提供可靠的传输服务,TCP 在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制。通过 TCP 连接传输的数据,无差错、不丢失、不重复、并且按序到达。
- 传输效率 :由于使用 TCP 进行传输的时候多了连接、确认、重传等机制,所以 TCP 的传输效率要比 UDP 低很多。
- 首部开销 :TCP 首部开销(20 ~ 60 字节)比 UDP 首部开销(8 字节)要大。
- 是否提供广播或多播服务 :TCP 只支持点对点通信,UDP 支持一对一、一对多、多对一、多对多;
- 是否有状态 :这个和上面的“是否可靠传输”相对应。TCP 传输是有状态的,这个有状态说的是 TCP 会去记录自己发送消息的状态比如消息是否发送了、是否被接收了等等。为此 ,TCP 需要维持复杂的连接状态表。而 UDP 是无状态服务,简单来说就是不管发出去之后的事情。
- 传输形式 : TCP 是面向字节流的,UDP 是面向报文的。
相关文章:

计算机网络八股文之TCP协议
TCP/IP模型 链路层 物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后再转化为1、0,也就是我们…...

【linux】linux中如何通过stress进行压力测试,原理解析与应用实战
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…...
python用波形显示udp数据实现一个模拟示波器
显示端代码: import socket import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np# UDP setup udp_ip = 0.0.0.0 # Listen on all network interfaces udp_port = 12345 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)…...

开源通用验证码识别OCR —— DdddOcr 源码赏析(二)
文章目录 前言DdddOcr分类识别调用识别功能classification 函数源码classification 函数源码解读1. 分类功能不支持目标检测2. 转换为Image对象3. 根据模型配置调整图片尺寸和色彩模式4. 图像数据转换为浮点数据并归一化5. 图像数据预处理6. 运行模型,返回预测结果 …...

【个人笔记】VCS工具与命令
Title:VCS工具学习 一 介绍 是什么? VCS (Verilog Compiler Simulator) 是synopsys的verilog 仿真软件,竞品有Mentor公司的Modelsim、Cadence公司的NC-Verilog、Verilog—XL. VCS能够 分析、编译 HDL的design code,同时内置了 仿…...

面试进去8分钟就出来了,问的问题有点变态。。。
从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%,这…...

探索MongoDB的Python之钥:pymongo的魔力
文章目录 探索MongoDB的Python之钥:pymongo的魔力背景:为什么选择pymongo?简介:pymongo是什么?安装:如何将pymongo纳入你的项目?基础用法:五个核心函数介绍1. 连接到MongoDB2. 选择数…...

【数据结构】顺序表和链表——顺序表(包含丰富算法题)
文章目录 1. 线性表2. 顺序表2.1 概念与结构2.2 分类2.2.1 静态顺序表2.2.2 动态顺序表 2.3 动态顺序表的实现2.4 顺序表算法题2.4.1 移除元素2.4.2 删除有序数组中的重复项2.4.3 合并两个有序数组 2.5 顺序表问题与思考 1. 线性表 线性表(linear list)…...

pod基础和镜像拉取策略
目录 pod概念 pod的分类 1.基础容器 pause 2.初始化容器 init 实验:定义初始化容器 init容器的作用 实验:如何在容器内部进行挂载 镜像拉取策略 pod概念 pod是k8s里面的最小单位,pod也是最小化运行容器的资源对象。容器是基于pod在k…...

53 mysql pid 文件的创建
前言 接上一篇文章 mysql 启动过程中常见的相关报错信息 在 mysql 中文我们在 “service mysql start”, “service mysql stop” 经常会碰到 mysql.pid 相关的错误信息 比如 “The server quit without updating PID file” 我们这里来看一下 mysql 中 mysql.pid 文件的…...

前端---对MVC MVP MVVM的理解
就需要从前端这些年的从无到有、从有到优的变迁过程讲一下。 1. Web1.0时代 在web1.0时代并没有前端的概念,开发一个web应用多数采用ASP.NET/Java/PHP编写,项目通常用多个aspx/jsp/php文件构成,每个文件中同时包含了HTML、CSS、JavaScript、…...

深度学习 --- VGG16能让某个指定的feature map激活值最大化图片的可视化(JupyterNotebook实战)
VGG16能让某个指定的feature map激活值最大化图片的可视化 在前面的文章中,我用jupyter notebook分别实现了,预训练好的VGG16模型各层filter权重的可视化和给VGG16输入了一张图像,可视化VGG16各层的feature map。深度学习 --- VGG16卷积核的可…...

1990-2022年各地级市gdp、一二三产业gdp及人均gdp数据
1990-2022年各地级市gdp、一二三产业gdp及人均gdp数据 1、时间:1990-2022年 2、来源:城市统计年鉴 3、指标:年度、城市名称、城市代码、城市类别、省份标识、省份名称、国内生产总值/亿元、第一产业占GDP比重(%)、第二产业占GDP比重(%)、第…...

c++ 原型模式
文章目录 什么是原型模式为什么要使用原型模式使用场景示例 什么是原型模式 用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象,简单理解就是“克隆指定对象” 为什么要使用原型模式 原型模式(Prototype Pattern)是…...
论tomcat线程池和spring封装的线程池
Tomcat 中的线程池是什么? 内部线程池:Tomcat 确实有一个内部的线程池,用于处理 HTTP 请求,通常是org.apache.tomcat.util.threads.ThreadPoolExecutor 类的实例。这个线程池专门用于处理进入的 HTTP 请求和发送响应。可以通过 T…...

阿里P7大牛整理自动化测试高频面试题
最近好多粉丝咨询我,有没有软件测试方面的面试题,尤其是Python自动化测试相关的最新面试题,所以今天给大家整理了一份,希望能帮助到你们。 接口测试基础 1、公司接口测试流程是什么? 从开发那边获取接口设计文档、分…...
vue如何实现路由缓存
(以下示例皆是以vue3vitets项目为例) 场景一:所有路由都可以进行缓存 在渲染路由视图对应的页面进行缓存设置,代码如下: <template><router-view v-slot"{ Component, route }"><transiti…...
基于Openjdk容器打包运行jar程序
文章目录 应用场景基于Openjdk容器打包运行jar程序1.编译项目成jar包2.构建Dockerfile文件精简版-含jar包精简版-不含jar包带注释版-含jar包 3.编译Dockerfile成镜像。4.运行镜像: 应用场景 部署多版本jdk的应用程序。 基于Openjdk容器打包运行jar程序 1.编译项目…...

DNN学习平台(GoogleNet、SSD、FastRCNN、Yolov3)
DNN学习平台(GoogleNet、SSD、FastRCNN、Yolov3) 前言相关介绍1,登录界面:2,主界面:3,部分功能演示如下(1)识别网络图片(2)GoogleNet分类…...
HTTP协议(超文本传输协议)
HTTP请求消息 http请求消息组成: 请求行 :包含请求的方法 操作资源的地址 协议的版本号 http请求方法: GET:从服务器获取资源 POST:添加资源信息 PUT:请求服务器更新资源信息 DELETE:请…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...

基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)
cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...

sshd代码修改banner
sshd服务连接之后会收到字符串: SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢? 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头,…...