网络原理(协议)

应用层

自定义数据组织格式:

1. 行文本

**2.xml(标签):**比较原始,可读性好,冗余较多

复制代码
<request>
    <userId>1000</userId>
    <position>USA</position>
</request>

**3. json:**主流方式,可读性好,冗余一般

复制代码
{
    "userId":1000,
    "position":"USA"
}

**4. protobuf:使用二进制,**高性能场景下使用的方式,可读性差,冗余最小

现成的协议:

FTP:文件传输

SSH :远程操作主机

telnet:网络调试工具

HTTP:协议

.....

DNS

DNS是一整套从域名映射到主机的系统 ,TCP/IP使用IP地址 来确定网络上的一台主机或一个程序 ,但是IP地址不方便记忆。于是人们就发明了域名 ,域名是一个字符串,并且使用Hosts 文件来记录域名和IP的映射关系。随着网络的发展,每天都有数以万计的网站建立,也有数以万计的网站消失,所以无法在本地实时维护Hosts 文件。于是就演化出了域名服务器,通过访问域名服务器来获取对应的IP地址。

DNS是应用层协议 ,底层使用UDP 进行解析,浏览器也会对DNS的结果进行缓存

传输层

UDP协议

协议端格式

长度属性:16bit位 ,表示UDP最大可以传输64KB内容

校验和: 使用CRC校验和 ,把数据包每个字节都当成一个整数相加,最后的结果就是校验和。如果校验和出错,直接舍弃

UDP特点

无连接: 知道对端的IP和端口号就可以直接进行传输,不需要建立连接(对端没有保存发送端的信息)

**不可靠:**没有确认机制,也没有重传机制,发送之后就不管看

面向数据报: 不能够灵活控制读写的次数和数量,发送一个100字节的报文 ,只能一次接收100字节,不能10字节接十次

基于UDP的应用层协议

NFS:网络文件系统

TFTP:简单文件传输协议

DHCP:动态主机配置协议

BOOTP:启动协议,用于无盘启动

DNS:域名解析协议

TCP协议

1. 32位序号/确认序号: 保证数据不丢失,不乱序,不重复

2. 首部长度: 标识该TCP报头有多少个32bit(四字节) ,所以TCP头部长度 最大值是 15*4=60字节

3. 6位标记位:

URG:紧急指针是否有效

ACK:确认号是否有效

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

SYN:请求建立连接 ,携带SYN标识的称为同步报文段

FIN: 通知对端,本端要释放连接 ,称为结束报文段

4. 16位校验和:发送端填充(包含头部和载荷),接收端校验不通过,则舍弃

5. 16位紧急指针: 标识哪部分数据是紧急数据,直接从某个指定的序号读取

确认应答机制(ACK)

保证数据不丢失,不乱序,不重复

为确保TCP字节流传输的顺序,避免后传先至的问题,TCP为载荷中每个字节的数据 都进行了编号,当接收方接收到数据之后,会知道这个数据的起始编号(32位序号SN) ,根据载荷长度 ,可以计算出下一个数据 的起始编号,在返回给发送方的TCP报头中的32位确认序号中,标记这个数据

如果1001编号的数据,比0编号的数据先到,read()也不会读数据,而是等0号数据到达,在"接收缓存区"排好序之后 ,在进行读操作

超时重传

如果发送方达到一定时间 ,还没有收到ACK ,那么发送方会认为发生了丢包 ,这时就会进行重传

发送方无法区分是数据丢失还是ACK丢失 ,都会触发重传操作。如果是因为ACK丢失造成了重传,那么"数据缓冲区"也会进行一次去重操作

通过确认应答和超时重传 保证了TCP的可靠传输

连接管理

这里的连接表示通信双方保存对方的信息

建立连接(三次握手):

服务器启动,调用系统Listen api, 进入监听状态

1. 客户端调用connec t系统调用,发送SYN报文SYN=1 ,携带客户端初始序列号ISN(c) ),进入SYN_SENT状态

2. 服务器 收到客户端的SYN报文,返回SYN + ACK报文 (SYN=1,ACK=1,确认字号段=c+1 ,携带服务器初始序列号ISN(s) ),发送之后进入SYN_RCVD状态

3. 客户端收到SYN+ACK报文,发送ACK报文 (SYN=0,ACK=1,确认字号段=s+1),发送完变为ESTABLISHED 状态。服务器收到客户端的ACK,进入ESTABLISHED状态,全双工的TCP连接成功建立

ESTABLISHED:连接建立完毕,随时可以发送数据

目的: 为了确保网络连接正常客户端与服务器的发送能力和接收能力均正常以及协商数据

断开连接(四次挥手)

1. A给B发送FIN报文 ,表示准备断开连接 ,发送之后进入FIN_WAIT_1状态

2. B 收到FIN报文,向A返回ACK应答报文 ,进入CLOSE_WAIT状态

3. B 调用socket.close() 方法,向A发送FIN报文 ,进入LAST_ACK状态

4. A 收到FIN,向B发送ACK应答报文 ,B收到ACK应答报文后,关闭通信 。A经过TIME_WAIT状态后,也关闭通信

CLOSE_WAIT :**等待应用层调用socket.close()**关闭连接的状态

TIME_WAIT: 等待时间为2*MSL(TCP报文最大生存时间)

1. 保证在两个传输方向上的尚未被接收到的或是迟到的报文都已消失(否则服务器立即重启,可能会接收到上个进程的数据)

2. 在理论上保证最后一个报文可靠到达 (假设最后一个ACK出现丢包,B会对重传FIN报文,此时A处于TIME_WAIT 状态,接收到FIN报文后可以重发ACK

A发送FIN仅关闭了A -> B的通道A仍可接收B的数据

B发送FIN才关闭B->A的通道

滑动窗口

对于每发送一次数据段,都要给一个ACK确认应答,收到ACK后才能传输下一个数据。这样虽然安全,但是性能比较差 。我们可以一次发送多条数据,这样可以大大提高性能。

窗口大小:无需确认应答而可以继续发送确认应答的最大值 ,上图的窗口大小就是4000字节

1. 发送前4个数据时,无需等待ACK,直接发送

  1. 收到第一个ACK后继续发送第五段数据

  2. 操作系统会开辟发送缓冲区 来记录当前还有哪些数据没有应答 ,只有确认应答过的数据, 才能从缓冲区删掉

可能会出现的问题

1. 数据报已到达,ACK被丢了: 不用处理,因为可以通过后续的ACK进行确认

2. 数据报丢失: 接收端会一直发送ACK =1应答报文 ,来索取1~1000的数据报 。当收到1~1000的数据报,返回的就是4001。因为1001~4000的数据已经收到,并存放到接收缓冲区中

这种机制也称为快速重传

流量控制

接收端处理数据的速度是有限的,如果发送端发的数据太快,导致接收端的接收缓冲区被装满。这个时候再次发送,也没有任何意义。因此TCP支持根据接收端的处理能力动态决定发送端的发送速度 。这个机制就是流量控制

  1. 接收端可以将自己接收缓冲区剩余的空间大小 放入 TCP报头的窗口大小字段 。通过ACK来告知发送端

  2. 通过接收到的窗口大小字段,发送方就会动态调整发送速度 。当窗口大小字段为0 时,表示接收方接收缓冲区已满 ,发送方停止发送数据

  3. 之后,发送方每隔一段之间会发送一个窗口探测包 ,用来获取接收端此时的可用接收缓冲区大小

TCP首部40字节的选项中还包含了一个窗口扩大因子M ,所以实际窗口大小可以是 窗口字段的值<<M位 ,也就是乘以2^M

拥塞控制

TCP引入慢启动机制:

  1. 先将窗口大小设置为1 ,然后窗口大小再指数级增长

  2. 增长到ssthresh初始值 ,再成倍数增长 ,直到出现丢包

  3. 出现丢包后,将窗口大小设置为一个新的ssthresh值 ,然后继续成倍数增长

少量的丢包,只是触发超时重传,大量丢包才认为是网络堵塞

流量窗口和拥塞控制 都是TCP协议想尽可能快的把数据传输给对方,两者取小值

延迟应答

接收方通过延时返回ACK应答 ,利用这段时间消耗接收缓冲区中的数据 ,最终只返回最后一次的ACK报文。这样窗口越大网络吞吐量就越大,传输效率就越高

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

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

捎带应答

在延迟应答的基础上,可以将ACK和响应一同返回

面向字节流

创建一个TCP的socket,同时在内核里会创建一个发送缓冲区和接收缓冲区 。调用write时,数据会先写入到发送缓冲区 中。接收数据也是从接收缓冲区中拿数据

TCP的一个连接,既有发送缓冲区 ,又有接收缓冲区 。既可以读数据 ,又可以写数据 ,这个概念称为全双工

粘包问题

粘包问题的包是应用层的数据包 ,在TCP的协议头中,没有报文长度标识。站在传输层角度,TCP是一个一个报文过来的,按照序号排好序放在缓冲区里。占在应用层角度,看到的只是连续的字节数据不知道从哪开始,从哪结束

对于定长的包 ,保证每次都按固定大小读取

对于变长的包 ,可以在包头位置约定一个包总长度的字段 ,或者可以在包和包之间使用明确的分隔符

异常情况

进程终止:

进程终止/机器重启: 释放文件描述符表,仍然可以正常发送FIN,和正常关闭没有区别

机器掉电:

接收方突然掉电:发送方 接收不到ACK,首先会触发超时重传 。超时重传达到一定次数,就会触发**"重置TCP连接"** ,发送方发送复位报文 。如果复位报文还是没有ACK,那么发送方只好单方面释放连接

发送发突然掉电: 接收方不清楚发送方是掉电了,还是暂时没有数据发送。等到一定时间,接收方会发送一个**"心跳包"(周期性发送)** ,不携带业务数据,只是为了触发ACK。如果没有ACK响应,接收方就会释放连接

网络层

地址管理: 使用IP地址这样的概念,标识网络上某个设备的位置

路由选择: 在两个通信节点之间,规划出一个合理的路径

IP协议

主机: 配有IP地址 ,但是不进行路由控制设备

路由器: 即配有IP地址 ,又能进行路由控制

节点:主机和路由器的总称

协议头格式

1. 四位版本号: 指定IP协议的版本,对于IPv4就是4

2**. 4位头部长度:** 标识该报头有多少个32bit(四字节) ,所以头部长度最大值是15*4=60字节

3. 8位服务类型: 三位优先权字段(已弃用)4位TOS字段,和1位保留字段(必须置为0),4. 4位TOS分别表示:最小延迟,最大吞吐量,最高可靠性,最小成本。这四种相互冲突,因此只能选择一个。

5. 16位总长度: IP数据报整体占用多少字节

6. 16位标识ID:

拆包: 把拆出来的包设置为相同的ID

组包:相同标识的数据包组合到一起

13位分片偏移:

表示当前分片在原报文中处在哪个位置,实际偏移的字节数是这个值*8得到的

3位标志字段:

第一位保留位,第二位 设为1表示不分片 ,如果分片的话,第三位 置为1,其余 两位置为0

7. 8位生存空间: 一个IP数据报,能够在网络上传输的最大时间 ,单位是次数。IP数据报每次经过一个路由器转发一次,TTL-1,TTL减为0还无法到达,则会被丢弃。

8. 8位协议: 表示上层协议的类型

9. 16位头部校验和: 使用CRC进行校验,来鉴别头部是否损坏

地址管理

网段划分

将一个IP地址分为两个部分,网络号+主机号

网络号: 保证相互连接两个网段 内具有不同的标识

主机号: 同一网段内主机之间 具有相同的网络号,不同的主机号

不同子网就是将网络号相同的主机放到一起

DHCP技术: 自动给子网内新增的主机节点分配IP地址

网段划分方式:CIDR

引入一个额外的子网掩码(32位正整数)区分网络号和主机号

子网掩码前几位都是1 ,最后几位都是0 ,将IP与子网掩码进行按位与操作 ,得到的结果就是网络号

家用网络前24 位为网络号 ,后8位为主机号 ,子网掩码就为255.255.255.0

也可使用IP/N 来简洁表示IP地址和子网掩码 198.168.0.1/24

私有IP和公网IP

如果一个组织内部组建局域网,IP地址只用于局域网内通信,而不直接连到Internet上。局域网内的所有设备使用同一个公网IP ,互相之间使用不同的私有IP

私有IP格式:
10.*

172.16.到172.31.

192.168.*

包含在这个范围内的都称之为私有IP,其余称之为公网IP

路由器

一个路由器有两个IP地址 ,一个是WAN口IP ,另一个是LAN口IP(子网IP)

通过LAN口连接的设备,都属于在同一子网中。

每一个家用路由器,又作为运营商路由器子网 中的一个节点,这样的运营商路由器可能会有很多层级,最外层的运营商路由器的WAN口就是一个公网IP

特殊IP地址

主机号全部为0 :网段,代表整个局域网

主机号全部为1广播地址 ,给同一子网中所有的主机 都发送数据包,必须通过UDP进行传输,TCP不支持广播

127.* :用于本机环回测试 ,通常为127.0.0.1

IP地址的数量限制

IP地址是一个四字节正整数 ,最大只能表示43亿左右个IP地址。

**1. 动态分配IP地址:**只给接入网络的设备分配IP地址,同一个MAC地址的设备,每次上网得到的IP地址不一定是相同的

2. NAT技术: 全称是网络地址转换技术

**1.**同一局域网下,设备A访问设备B,IP本身不重复,NAT不起作用

**2.**公网设备A访问公网设备B,IP本身不重复,NAT不起作用

  1. 不同局域网的设备A访问设备B,NAT不允许

**4.**公网设备A访问局域网设备B,NAT不允许

**5.**局域网设备A,访问公网设备B,NAT起作用:

局域网设备访问公网设备,触发网络地址映射 ,将局域网IP映射为路由器的公网IP ,通过这个公网IP对公网设备进行访问。如果局域网内,两个私有IP不同端口号不同 的设备访问同一个公网IP,经过网络地址映射,得到的公网IP相同,相互之间使用端口号 区分。对于局域网内两个私有IP不同,端口号相同的设备,则通过网络端口映射,映射为不同的端口

通常来说,家里的局域网IP会先转换为路由器的WAN口IP ,通过这个WAN口IP 访问运营商服务器逐层替换 ,最后变为公网IP

**3. IPv6(终极方案):**IPv6使用16字节128位的整数来表示IP地址,完全够用

路由管理

简单来说就是问路的过程,路由器通过维护路由表 来进行数据包的转发。当收到数据包时,路由器会提取目的IP地址 ,并于路由表中的网段进行最长匹配 。如果匹配成功,则转发给对应的 下一跳。如果所有的网段都不匹配,则按照默认路由转发 (默认网关,也就是上一级路由器)。

数据链路层

以太网不是一种具体的网络而是一种技术标准 ,既包含数据链路层 ,又包含物理层 。但凡是使用网线 上网的设备,走的都是以太网协议

MAC地址 (网卡的硬件地址):长度是48位,每个网卡都有一个唯一的MAC地址,是网卡出厂时确定的

IP与MAC的区别:

IP:描述路途总体的起点和终点

MAC:路途上每个区间的起点和终点,每经过一个节点,MAC地址都会改变

  1. 通过不同类型来区分载荷的格式,
相关推荐
编程牛马姐21 小时前
独立站SEO流量增长:提高Google排名的优化方法
前端·javascript·网络
2401_873479401 天前
如何从零搭建私有化IP查询平台?数据采集、清洗、建库到API发布全流程
服务器·网络·tcp/ip
FS_Marking1 天前
CWDM vs DWDM:区别是什么?
网络
Vis-Lin1 天前
BLE 协议栈:ATT 协议详解
网络·物联网·网络协议·iot·ble
lcxc1 天前
Mac M4超流畅运行Win版同花顺教程
网络
W.A委员会1 天前
常见网络攻击
网络·http·网络安全
zmj3203241 天前
CAN数据帧详解
网络·can·canfd·数据帧
无心水1 天前
OpenClaw技术文档/代码评审/测试用例生成深度实战
网络·后端·架构·测试用例·openclaw·养龙虾
深蓝海拓1 天前
基于QtPy (PySide6) 的PLC-HMI工程项目(十)框架初成的阶段总结
网络·笔记·python·学习·ui·plc
白羊by1 天前
Softmax 激活函数详解:从数学原理到应用场景
网络·人工智能·深度学习·算法·损失函数