网络传输层协议: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.

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

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

相关文章

【用Vscode实现简单的python爬虫】从安装到配置环境变量到简单爬虫以及python中pip和request,bs4安装

第一步:安装python包 可以默认,也可以选择自己想要安装的路径 第二步:配置python环境变量,找到我的电脑->属性->高级 然后将刚刚安装的路径配置到path路径下: 然后cmd 运行 输入python命令,如果出现…

FFmpeg aresample_swr_opts的解析

ffmpeg option的解析 aresample_swr_opts是AVFilterGraph中的option。 static const AVOption filtergraph_options[] {{ "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,{ .i64 AVFILTER_THREAD_SLICE }, 0, INT_MA…

Python数据可视化工具——Pyecharts

目录 1 简介绘图前先导包 2 折线图3 饼图4 柱状图/条形图5 散点图6 箱线图7 热力图8 漏斗图9 3D柱状图10 其他:配置项 1 简介 Pyecharts是一款将python与echarts结合的强大的数据可视化工具 Pyecharts是一个用于生成echarts图表的类库。echarts是百度开源的一个数据…

【JVM】JVM五大内存区域介绍

目录 一、程序计数器(线程私有) 二、java虚拟机栈(线程私有) 2.1、虚拟机栈 2.2、栈相关测试 2.2.1、栈溢出 三、本地方法栈(线程私有) 四、java堆(线程共享) 五、方法区&…

数据结构与算法基础-学习-27-图之最短路径之Dijkstra(迪杰斯特拉)算法

一、最短路径应用案例 例如从北京到上海旅游,有多条路可以到目的地,哪条路线最短,哪条路线最省钱,就是典型的最短路径问题。 二、最短路径问题分类 最短路径问题可以分为两类,第一类为:两点间最短路径。第…

【ArcGIS Pro二次开发】(54):三调名称转用地用海名称

三调地类和用地用海地类之间有点相似但并不一致。 在做规划时,拿到的三调,都需要将三调地类转换为用地用海地类,然后才能做后续的工作。 一般情况下,三调转用地用海存在【一对一,多对一和一对多】3种情况。 前2种情况…

敏捷项目经理和传统项目经理有哪些区别?

敏捷项目经理和传统项目管理有哪些区别,经常有咱们群里的伙伴们问,敏捷项目经理注重迅速响应需求变化、灵活应变,而传统项目经理更为注重计划的制定与执行。作为项目经理,敏捷也是必要的技能,今天就为大家分享一下敏捷…

Mac上安装sshfs

目录 写在前面安装使用参考完 写在前面 1、本文内容 Mac上安装sshfs 2、平台 mac 3、转载请注明出处: https://blog.csdn.net/qq_41102371/article/details/130156287 安装 参考:https://ports.macports.org/port/sshfs/ 通过port安装 点击啊insta…

【电网异物检测硕士论文摘抄记录】电力巡检图像中基于深度学习的异物检测方法研究

根据国家电力行业发展报告统计,截止到 2018 年,全国电网 35 千伏及以上的输电线路回路长度达到 189 万千米,220 千伏及以上输电线路回路长度达73 万千米。截止到 2015年,根据国家电网公司的统计 330 千伏及以上输电线路故障跳闸总…

经营简报及考核360表格

文章目录 经营简报效果图代码tableObjectSpanMethod.js 考核360委员会效果图 经营简报效果图不需要合并单元格且有汇总表头的 懒得封装了&#xff0c;所以整体没有封装 经营简报 效果图 代码 <template><el-tableref"tableRef":data"tableData.lengt…

【数据结构(C++版)】哈希表(散列表)

目录 1. 散列表的概念 2. 散列函数的构造方法 2.1 直接定址法 2.2 除留余数法 2.3 数字分析法 2.4 平方取中法 3. 处理冲突的方法 3.1 开放定址法 3.1.1 线性探测法 3.1.2 平方探测法 3.1.3 双散列法 3.1.4 伪随机序列法 3.2 拉链法&#xff08;链接法&#xff0…

BLE基础理论/Android BLE开发示例

参考&#xff1a;https://blog.csdn.net/qq_36075612/article/details/127739150?spm1001.2014.3001.5502 参考&#xff1a; https://blog.csdn.net/qq_36075612/article/details/122772966?spm1001.2014.3001.5502 目录 蓝牙的分类传统蓝牙低功耗蓝牙 蓝牙专业词汇&#xff…

了解Unity编辑器之组件篇Event(七)

Event&#xff1a;用于在对象之间进行通信和交互的机制。它可以帮助你实现触发和响应特定动作或状态的逻辑一、Event System&#xff1a;用于处理 UI 事件的系统组件 First Selected 属性&#xff1a;定义了在场景加载或 UI 激活时&#xff0c;哪个 UI 元素将成为首选的选中元素…

秋招备战笔试Day1

目录 单选 1. 在 Java 中&#xff0c;存放字符串常量的对象属于&#xff08; &#xff09;类对象。 2.已知如下类定义&#xff1a; 如下哪句可以正确地加入子类中&#xff1f; 3. 下列选项中属于面向对象编程主要特征的是&#xff08;&#xff09; 4.关于下列程序段的输出结…

7年经验之谈 —— 浅谈web性能测试

什么是性能测试&#xff1f; web性能应该注意些什么&#xff1f; 性能测试&#xff0c;简而言之就是模仿用户对一个系统进行大批量的操作&#xff0c;得出系统各项性能指标和性能瓶颈&#xff0c;并从中发现存在的问题&#xff0c;通过多方协助调优的过程。而web端的性能测试…

联发科CEO:未获准向华为供货,换机潮已过去,手机需求不会更差

据钜亨网报道&#xff0c;联发科近期召开了业绩说明会。蔡力行&#xff0c;该公司副董事长兼首席执行官&#xff0c;表明当前手机市场需求保持稳定&#xff0c;并且随着过去两年用户更换潮的过去&#xff0c;对手机市场明年有一定期望。 根据蔡力行的指示&#xff0c;联发科正在…

Notepad++工具通过正则表达式批量替换内容

1.每行末尾新增特定字符串 CtrlH弹出小窗口&#xff1b;查找目标输入$&#xff0c;替换为输入特定字符串&#xff1b;选中循环查找&#xff0c;查找模式选正则表达式&#xff1b;最后点击全部替换 2.每行行首新增特定字符串 CtrlH弹出小窗口&#xff1b;查找目标输入^&…

Windows如何安装Django及如何创建项目

目录 1、Windows安装Django--pip命令行 2、创建项目 2.1、终端创建项目 2.2、在Pycharm中创建项目 2.3、二者创建的项目有何不同 2.4、项目目录说明 1、Windows安装Django--pip命令行 安装Django有两种方式&#xff1a; pip命令行【推荐--简单】手动安装【稍微复杂一丢丢…

无涯教程-jQuery - Puff方法函数

吹气效果可以与show/hide/toggle一起使用。通过按比例放大元素并同时隐藏它&#xff0c;可以形成粉扑效果。 Puff - 语法 selector.hide|show|toggle( "puff", {arguments}, speed ); 这是所有参数的描述- model - 效果的模式。可以是"显…

【嵌入式Linux系统开发】——系统移植概述

目录 &#x1f349;&#x1f349;一、什么是嵌入式系统 &#x1f349;&#x1f349;二、嵌入式系统操作 &#x1f349;&#x1f349;三、嵌入式Linux的特点 &#x1f349;&#x1f349;四、嵌入式系统的组成 1、硬件和软件 2、硬件层 3、中间层 4、软件层 5、 功能层与执…