当前位置: 首页 > news >正文

网络传输层协议:UDP和TCP

背景知识

再谈端口号

端口号(Port)标识了一个主机上进行通信的不同的应用程序;

在TCP/IP协议中, 用 "源IP", "源端口号", "目的IP", "目的端口号", "协议号" 这样一个五元组来标识一个通信(可以通过 netstat -n查看); 

端口号范围划分

0 - 1023: 知名端口号, HTTP, FTP, SSH 比特科技 等这些广为使用的应用层协议, 他们的端口号都是固定的.

1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作系统从这个范围分配的.

认识知名端口号(Well-Know Port Number)

ssh服务器, 使用22端口

ftp服务器, 使用21端口

telnet服务器, 使用23端口

http服务器, 使用80端口

https服务器, 使用443

端口号配置文件可以在/etc/services文件查看

netstat

netstat是一个用来查看网络状态的重要工具.

语法:netstat [选项]

功能:查看网络状态

常用选项:

n 拒绝显示别名,能显示数字的全部转化成数字

l 仅列出有在 Listen (监听) 的服务状态

p 显示建立相关链接的程序名

t (tcp)仅显示tcp相关选项

u (udp)仅显示udp相关选项

a (all)显示所有选项,默认不显示LISTEN相关

pidof

在查看服务器的进程id时非常方便.

语法:pidof [进程名]

功能:通过进程名, 查看进程id

xargs:将管道内容拼接到当前指令之后

pidof [任务名]  |  xargs   kill -9

UDP协议

UDP协议端格式

 16位UDP长度, 表示整个数据报(UDP首部+UDP数据)的最大长度;

如果校验和出错, 就会直接丢弃;

UDP的特点

类似于发快递:

无连接: 知道对端的IP和端口号就直接进行传输, 不需要建立连接;

不可靠: 没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层 返回任何错误信息;

面向数据报: 不能够灵活的控制读写数据的次数和数量;(整发整取

面向数据报

应用层交给UDP多长的报文, UDP原样发送, 既不会拆分, 也不会合并;

用UDP传输100个字节的数据: 如果发送端调用一次sendto, 发送100个字节, 那么接收端也必须调用对应的一次recvfrom, 接收100个 字节; 而不能循环调用10次recvfrom, 每次接收10个字节

UDP协议首部中有一个16位的最大长度. 也就是说一个UDP能传输的数据最大长度是64K(包含UDP首 部).

然而64K在当今的互联网环境下, 是一个非常小的数字. 如果我们需要传输的数据超过64K, 就需要在应用层手动的分包, 多次发送, 并在接收端手动拼装;

TCP协议

TCP全称为 "传输控制协议(Transmission Control Protocol"). 人如其名, 要对数据的传输进行一个详细的控制;

 源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去;

32位序号/32位确认号: 控制数据接收和发送;

为什么要有32位序号/32位确认号?

以为TCP是全双工通信。

4位TCP报头长度: 表示该TCP头部有多少个32位bit(有多少个4字节); 所以TCP头部最大长度是15 * 4 = 60(报头总长度 = 4位TCP报头长度 * 4字节

6位标志位(决定TCP报文类型):

URG(带外数据): (如果数据想插队,越过缓冲区直接被读取)紧急指针(在有效载荷中的偏移量,只有一个字节是紧急数据)是否有效

ACK: 确认数据是否收到(正常通信都会置1)

PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走

RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段(服务器重启后,客户端发送报文,服务端发带RST的报文,链接复位

SYN: 请求建立连接(请求握手); 我们把携带SYN标识的称为同步报文段

FIN: 断开连接请求, 我们称携带FIN标识的为结束报文段

16位窗口大小: 填入自己的接收缓冲区剩余空间大小,流量控制

16位校验和: 发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含TCP首部, 也 包含TCP数据部分.

16位紧急指针: 标识哪部分数据是紧急数据;

40字节头部选项: 暂时忽略;

send和recv通过设置MSG_OOB读取/发送带外数据。

序号是发送端发送的数据段的序号(1~1000,就发1),确认序号是应答收到的数据段的序号+数据大小.(确认序号就是确认你在这个序号之前的数据都被我收到了)

超时重传机制(解决丢包问题)

超时没有接收到ACK应答有两种情况:

1.真的丢了

真的丢了也分为两种情况,正常数据段丢了或者确认数据段丢了。如果是正常数据段丢了,再发一次就行,如果是ACK应答丢了,再发一次之后,接收端再发一次ACK应答就行。

2.还在路上

如果是还在路上,那么重发会产生数据重复问题。

接收端会检验数据段的32位序号,如果重复就丢弃。

超时时间为(2^n) * 500ms

三次握手

为什么是三次握手?

因为链接需要被管理,先描述后组织,维护一个链接有时间成本和空间成本。

一次握手和两次握手可能会有SYN洪水,三次握手是验证全双工通信通畅的最小成本。

四次挥手

如果服务端出现大量的close_wait有两种可能:

1.没有close文件描述符

2.服务器有压力

主动断开连接的乙方为什么要维持一段时间(2 * MSL(60s))的TIME_WAIT状态?

1.保证最后一个ACK被收到

2.有可能在断开时,网络中有滞留的报文

当端口处于TIME_WAIT状态就不能被绑定,要解决这个问题只要在绑定套接字之前加入下面的代码就行:

socklen_t t = 1;
setsockopt(_listen_sock, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(t));

四次挥手也有可能变成三次挥手。

滑动窗口(类似于环形队列)

 既然这样一发一收的方式性能较低, 那么我们一次发送多条数据, 就可以大大的提高性能(其实是将多个段的等待时 间重叠在一起了).

 那么如果出现了丢包, 如何进行重传? 这里分两种情况讨论.

情况一: 数据包已经抵达, ACK被丢了.

只要最新的ACK(同时确认前面的数据都被成功接收)应答被收到,就可以忽略前面丢失的ACK 。

情况二: 数据包就直接丢了.

当某一段报文段丢失之后, 发送端会一直收到 1001 这样的ACK, 就像是在提醒发送端 "我想要的是 1001" 一样;

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

这个时候接收端收到了 1001 之后, 再次返回的ACK就是7001了(因为2001 - 7000)接收端其实之前就已 经收到了, 被放到了接收端操作系统内核的接收缓冲区中; 

流量控制

因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制(Flow Control);

流量控制是通过控制发送缓冲区的滑动窗口大小实现的:

滑动窗口 = min(拥塞窗口, 接收端缓冲区剩余空间)

拥塞控制

网络拥塞状态:由于网络拥堵,发送的报文大量丢失。

少量丢失报文可以通过超时重传机制解决,但如果从宏观来看,由于网络原因造成网络拥塞状态,就不能简单重传。如果只是简单重传只会加重网络拥堵的状况。

为了解决这个问题:TCP引入 慢启动机制, 先发少量的数据,探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输数据;

拥塞窗口是一个数字,一开始为1.

 ssthred(慢启动阈值),拥塞窗口达到ssthred之后线性增长,当线性增长到拥塞状态时,更新拥塞避免阈值,更新ssthred为拥塞避免阈值的一半。

延迟应答

如果接收数据的主机立刻返回ACK应答, 这时候返回的窗口可能比较小.(有赌的成分)

假设接收端缓冲区为1M. 一次收到了500K的数据; 如果立刻应答, 返回的窗口就是500K;

但实际上可能处理端处理的速度很快, 10ms之内就把500K数据从缓冲区消费掉了;

在这种情况下, 接收端处理还远没有达到自己的极限, 即使窗口再放大一些, 也能处理过来;

如果接收端稍微等一会再应答, 比如等待200ms再应答, 那么这个时候返回的窗口大小就是1M;

一定要记得, 窗口越大, 网络吞吐量就越大, 传输效率就越高. 我们的目标是在保证网络不拥塞的情况下尽量提高传输 效率; 那么所有的包都可以延迟应答么? 肯定也不是;

数量限制: 每隔N个包就应答一次;

时间限制: 超过最大延迟时间就应答一次;

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

捎带应答

在延迟应答的基础上, 我们发现, 很多情况下, 客户端服务器在应用层也是 "一发一收" 的. 意味着客户端给服务器说 了 "How are you", 服务器也会给客户端回一个 "Fine, thank you";

那么这个时候ACK就可以搭顺风车, 和服务器回应的 "Fine, thank you" 一起回给客户端

面向字节流

由于缓冲区的存在, TCP程序的读和写不需要一一匹配, 例如:

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

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

粘包问题

tcp的报文需要自己设置协议去把数据包分开。

那么如何避免粘包问题呢? 归根结底就是一句话, 明确两个包之间的边界.

1.  对于定长的包, 保证每次都按固定大小读取即可; 例如上面的Request结构, 是固定大小的, 那么就从缓冲区从头开始按sizeof(Request)依次读取即可;

2.  对于变长的包, 可以在包头的位置, 约定一个包总长度的字段, 从而就知道了包的结束位置;

3.  对于变长的包, 还可以在包和包之间使用明确的分隔符(应用层协议, 是程序猿自己来定的, 只要保证分隔 符不和正文冲突即可);

理解 listen 的第二个参数

对于服务器, listen 的第二个参数设置为 2, 并且不调用 accept

 

 

客户端状态正常, 但是服务器端出现了 SYN_RECV 状态, 而不是 ESTABLISHED 状态 这是因为, Linux内核协议栈为一个tcp连接管理使用两个队列:

1. 半链接队列(用来保存处于SYN_SENT和SYN_RECV状态的请求)

2. 全连接队列(accpetd队列)(用来保存处于established状态,但是应用层没有调用accept取走的请求)

而全连接队列的长度会受到 listen 第二个参数的影响. 全连接队列满了的时候, 就无法继续让当前连接的状态进入 established 状态了. 这个队列的长度通过上述实验可知, 是 listen 的第二个参数 + 1.

相关文章:

网络传输层协议:UDP和TCP

背景知识 再谈端口号 端口号(Port)标识了一个主机上进行通信的不同的应用程序; 在TCP/IP协议中, 用 "源IP", "源端口号", "目的IP", "目的端口号", "协议号" 这样一个五元组来标识一个通信(可以通过 netstat -…...

ElementUI Select选择器如何根据value值显示对应的label

修改前效果如图所示&#xff0c;数据值状态应显示为可用&#xff0c;但实际上仅显示了状态码1&#xff0c;并没有显示其对应的状态信息。在排查了数据类型对应关系问题后&#xff0c;并没有产生实质性影响&#xff0c;只好对代码进行了如下修改。 修改前代码&#xff1a; <…...

Kotlin 内联函数语法之let、apply、also、run、with的用法与详解

一、介绍 kotlin的语法千奇百怪&#xff0c;今天我们将介绍项目中频率使用比较高的几个内联函数。 二、什么叫内联函数&#xff1f; 内联函数 的语义很简单&#xff1a;把函数体复制粘贴到函数调用处 。使用起来也毫无困难&#xff0c;用 inline关键字修饰函数即可。 语法&a…...

Swift 中如何判断是push 过来的页面 还是present过来的 页面

在 Swift 中&#xff0c;可以通过检查当前视图控制器的 presentingViewController 属性来判断是通过 push 过来的页面还是 present 过来的页面。 下面是一个示例代码&#xff0c;展示如何判断是通过 push 还是 present 过来的页面&#xff1a; if let presentingViewControll…...

基于K8s环境·使用ArgoCD部署Jenkins和静态Agent节点

今天是「DevOps云学堂」与你共同进步的第 47天 第⑦期DevOps实战训练营 7月15日已开营 实践环境升级基于K8s和ArgoCD 本文节选自第⑦期DevOps训练营 &#xff0c; 对于训练营的同学实践此文档依赖于基础环境配置文档&#xff0c; 运行K8s集群并配置NFS存储。实际上只要有个K8s集…...

874. 模拟行走机器人

874. 模拟行走机器人 机器人在一个无限大小的 XY 网格平面上行走&#xff0c;从点 (0, 0) 处开始出发&#xff0c;面向北方。该机器人可以接收以下三种类型的命令 commands &#xff1a; -2 &#xff1a;向左转 90 度-1 &#xff1a;向右转 90 度1 < x < 9 &#xff1a;…...

【Linux】- RPM 与 YUM

RPM 与 YUM 1.1 rpm 包的管理1.2 rpm 包的简单查询指令1.3 rpm 包的其它查询指令&#xff1a;1.4 卸载 rpm 包&#xff1a;2.1 安装 rpm 包3.1 yum3.2 yum 的基本指令3.3 安装指定的 yum 包3.4 yum 应用实例&#xff1a; 1.1 rpm 包的管理 介绍 rpm 用于互联网下载包的打包及安…...

Visual Studio 2015编译器 自动生成 XXX_EXPORTS宏

XXX_EXPORTS宏 XXX_EXPORTS宏是由Visual Studio 2015编译器自动生成的。这个宏用于标识当前项目是一个导出符号的动态链接库&#xff08;DLL&#xff09;项目。在使用Visual Studio 2015创建Win32项目时&#xff0c;编译器会自动添加这个宏到项目的预定义宏中。 这个宏的作用…...

HTML5的应用现状与发展前景

HTML5&#xff0c;作为Web技术的核心&#xff0c;已经深深地改变了我们看待和使用Web的方式。它不仅提供了数不尽的新特性和功能&#xff0c;还使得Web设计和开发更加互动、更加直观。这篇文章将探讨HTML5的当前应用现状&#xff0c;以及它的未来发展前景。 HTML5的应用现状 H…...

day44-Spring_AOP

0目录 1.2.3 1.Spring_AOP 实体类&#xff1a; Mapper接口&#xff1a; Service和实现类&#xff1a; 测试1&#xff1a; 运行后&#xff1a; 测试2&#xff1a;无此型号时 测试3&#xff1a;库存不足时 解决方案1&#xff1a;事务声明管理器 测试&#xff1a…...

selenium IDE 接入jenkins-转载

Selenium-IDE脚本录制,selenium-side-runner自动化测试教程_51CTO博客_selenium ide录制脚本 备忘录...

云计算结合数据科学突破信息泛滥(下)

大家好&#xff0c;本文将继续讨论云计算结合数据科学突破信息泛滥的相关内容&#xff0c;讲述其余三个关键组成部分。 3.数据清理和预处理 收集数据并将其存储在云端之后&#xff0c;下一步是将数据进行转换。因为原始数据经常包含错误、不一致和缺失的值&#xff0c;这些都…...

蓝桥杯单片机第十二届国赛 真题+代码

iic.c /* # I2C代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行编写相关代码或以该代码为基础&#xff0c;根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求&#xff0c;进行代码调试和修改。 */ #include <STC1…...

MyBatis学习笔记之缓存

文章目录 一级缓存一级缓存失效 二级缓存二级缓存失效二级缓存相关配置 MyBatis集成EhCache 缓存&#xff1a;cache 缓存的作用&#xff1a;通过减少IO的方式&#xff0c;来提高程序的执行效率 mybatis的缓存&#xff1a;将select语句的查询结果放到缓存&#xff08;内存&…...

​小程序 WxValidate.js ​再次封装

util.js // 合并验证规则和提示信息 const filterRules (objectItem) > {let rules {}, messages {};for (let key in objectItem) {rules[key] objectItem[key].rulesmessages[key] objectItem[key].message}return { rules, messages } }module.exports {filterRule…...

redis 第三章

目录 1.主从复制 2.哨兵 3.集群 4.总结 1.主从复制 结果&#xff1a; 2.哨兵 3.集群 4.总结 通过集群&#xff0c;redis 解决了写操作无法负载均衡&#xff0c;以及存储能力受到单机限制的问题&#xff0c;实现了较为完善的高可用方案。...

MYSQL常见面试题汇总

MYSQL常见面试题汇总 1. 什么是MYSQL&#xff1f;它有哪些特点&#xff1f; MYSQL是一种开源的关系型数据库管理系统。它具有以下特点&#xff1a; 高性能&#xff1a;MYSQL能够处理大量的并发请求&#xff0c;并提供快速的响应时间。可靠性&#xff1a;MYSQL具有数据持久化…...

Java接口通过token登录实现页面跳转到登录成功后的页面

首先&#xff0c;你需要在接口请求中将token作为参数传递给后端&#xff0c;后端需要对token进行验证并获取登录用户的信息。 在验证通过后&#xff0c;你可以将登录成功后的页面链接返回给前端&#xff0c;前端通过跳转到该链接来实现页面跳转。 以下是一个简单的Java代码演…...

Linux-文件管理

1.文件管理概述 1.Bash Shell对文件进行管理 谈到Linux文件管理&#xff0c;首先我们需要了解的就是&#xff0c;我们要对文件做些什么事情&#xff1f; 其实无非就是对一个文件进行、创建、复制、移动、查看、编辑、压缩、查找、删除、等等 例如 : 当我们想修改系统的主机名…...

Android getevent用法详解

TP驱动调试分享——基于Qualcomm SDM710平台Android9.0&#xff0c;TP 采用I2C方式和CPU进行通信_高通tp驱动_永恒小青青的博客-CSDN博客 手机触摸屏扫描信号实测波形_触摸屏报点率_AirCity123的博客-CSDN博客 如何查看TP报点率&#xff1f;触摸TP查看详细信息 adb shell ge…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...