目录
1. 网络发展
- 网络互联
- 多台计算机连接在一起,完成数据共享。
- 局域网
- 同一根网线上连接的所有主机,可以称为一个局域网。
- 在同一个局域网中通信,可以直接互相传输数据。
- 若需要跨网络传输数据,则需要借助路由器及交换机连接。
- 广域网
- 将距离很远的计算机连在一起。
- 局域网和广域网只是相对的概念
2. 网络通信协议
-
2.1 初始
- 协议
- 在具体进行某项事务之前,双方使用机器语言做的一项约定。
- 网络通信协议
- 通信双方约定好的网络通信数据信号的解析式
- 协议
-
2.2 网络分层
- 在网络通信环境中,按照服务、接口、协议将整个通信过程进行分层。
- 上下层只有接口的交互
- 优点
- 将提供的服务、协议以及接口进行封装之后,使用起来及替换更加方便,实现起来也更加清晰简单。
-
2.2.1 OSI七层参考模型
- 自上向下
- 应用层 -> 表示层 -> 会话层 -> 传输层 -> 网络层 -> 数据链路层 -> 物理层
- 意义:便于维护
- 自上向下
-
2.2.2 TCP / IP 五层模型
- TCP / IP 是一组协议,称之为TCP / IP 协议簇。最典型的两个协议:TCP IP
- 自上向下
- 应用层 -> 传输层 -> 网络层 -> 数据链路层 -> 物理层
- 应用层
- 负责应用程序之间的沟通
- 最常用协议:http协议(负责网页资源的传输)、ftp协议(负责文件传输)
- 传输层
- 负责端与端之间的数据传输
- 最典型协议:tcp协议、udp协议
- 网络层
- 负责地址管理与路由选择(广域网中数据通信的问题)
- 最典型协议:IP协议
- 最典型设备:路由器(路由选址)
- 数据链路层
- 负责相邻设备之间的数据帧传输(局域网中数据通信的问题)
- 最典型协议:以太网协议eth
- 最典型设备:交换机(数据转发)
- 物理层
- 负责光电信号的传输
- 最典型协议:以太网协议
- 最典型设备:集线器(信号放大,使得信号传输的更远)
3. 数据包封装和分用
-
不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层叫做数据报 (datagram),在链路层叫做帧(frame)。
- 应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装 (Encapsulation).。
- 首部信息中包含了一些类似于首部有多长,载荷(payload)有多长,上层协议是什么等信息。
- 数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,根据首部中的 "上层协议字段" 将数据交给对应的上层协议处理。
-
3.1 封装
- 将键盘录入的内容封装应用层的协议头
- -> 应用层处理完毕,将数据传给传输层
- -> 添加tcp或udp协议头,将数据传给网络层
- -> 添加ip协议头,将数据传给数据链路层
- -> 添加以太头(由于负责数据帧的传输,需要知道数据帧的开始与结束 -> 需要帧头和帧尾进行标记)
- 通过物理光电信号,进行物理传输
- 将键盘录入的内容封装应用层的协议头
-
3.2 分用
- 去掉以太头的帧头与帧尾,解析出数据,交由网络层
- -> 去掉ip头,解析出数据,交由传输层
- -> 去掉tcp或udp头,解析出数据,交由应用层
- -> 应用层进行解析
- 去掉以太头的帧头与帧尾,解析出数据,交由网络层
4. 应用层
负责应用程序之间的数据沟通
-
4.1 数据的序列化与反序列化
- 数据进行可持续化存储(向磁盘存储)时,数据的组织就是序列化。
-
4.2 HTTP 超文本传输协议
- 应用层的协议都是自定制协议,使用场景、使用频率以及使用者多的协议,就成为了知名协议。
- http是一个明文传输协议,传输层使用tcp协议
-
4.2.1 url 统一资源定位符(网址)
- http://username:password@www.baidu.com:80/index.html?wd=c%2B%2B#ch
- 协议名://用户名:密码@服务器地址:端口/资源路径?查询字符串#片段标识符
-
4.2.2 urlencode / urldecode
- 因为http的url中特殊字符一般都有特殊含义,因此提交的查询字符中不能随意出现特殊字符。如果非要有特殊字符,需要对特殊字符进行转义(url编码 urlencode)
- 编码 urlencode
- 将一个字节的前四位/后四位转换为16进制数据,合到一起进行显示,使用%标识经过url编码过的字符。
- + -> %2B
- 将一个字节的前四位/后四位转换为16进制数据,合到一起进行显示,使用%标识经过url编码过的字符。
- 解码 urldecode
-
4.2.3 http协议格式
- 请求 request:
- 首行\r\n头部(key:val\r\nley:val\r\n)空行(\r\n)正文
- 首行
- 包括METHOD、URL、VERSION\r\n
- GET https://www.baidu.com/index.html HTTP/1.1
- 常见请求方法:GET、POST
- 区别
- GET没有正文:提交的数据在url中
- POST有正文:提交的表单数据
- 都是用于请求获取资源
- 区别
- 常见请求方法:GET、POST
- 头部
- 以多个键值对组成,每个键值对之间以\r\n间隔(key:val\r\n)
- Host:服务器主机地址
- Content-Length:正文长度(知道正文何时结束)
- Content-Type:正文类型
- Referer:发起路径
- Cookie:保存登录信息
- 空行 \r\n\
- 正文
- 首行
- 首行\r\n头部(key:val\r\nley:val\r\n)空行(\r\n)正文
- 响应 response:
- 首行
- 包括VERSION、STATU、STATU_DESC\r\n
- STATU状态码:表示服务端如何处理客户端的当次请求
- 1XX:描述信息
- 2XX:正常处理
- 3XX:重定向,与Location配合使用
- 4XX:客户端错误
- 5XX:服务器错误
- STATU状态码:表示服务端如何处理客户端的当次请求
- 包括VERSION、STATU、STATU_DESC\r\n
- 头部
- 以多个键值对组成,每个键值对之间以\r\n间隔(key:val\r\n)
- Location:重定向位置
- Transfer-Encoding:传输编码方式
- chunked:在返回每一段数据前告诉客户端数据的长度
- Cookie:存储客户端访问网站的信息(认证信息等)
- 空行 \r\n\
- 正文
- 首行
- 请求 request:
5. 传输层
负责端与端之间的数据传输
-
5.1 UDP协议
-
5.1.1 特点
- 无连接、不可靠、面向数据报
- 优点:快,没有粘包问题
- 缺点:无法保证数据安全传输
-
5.1.2 协议格式
- 端口号 uh_sport、uh_dport
- 负责端与端之间传输
- 长度 uh_length
- udp数据包长度
- 使得udp每条数据之间都有明显的边界,不会出现粘包问题
- udp每个数据包的长度是有限制的 -> 不超过64k(因为udp头部当中有一个uh_ulen是u_int16_t,标记udp数据包长度,无符号两个字节最大长度就是65535)
- 传输大数据时,需要在应用层进行数据切分
- 因为udp不可靠传输,所以无法保证安全也无法保证包序。如果应用层进行分段,需要在应用层进行包序管理。
- udp数据包长度
- 校验和 uh_sum
- 校验数据包的完整性、正确性
- 计算方法:二进制反码求和
- 端口号 uh_sport、uh_dport
-
-
5.2 TCP协议
-
5.2.1 特点
- 有连接、可靠传输、面向字节流
-
5.2.2 协议格式
- 源端口、目的端口、序列号、确认序列号、校验和、窗口大小、头部大小、6位保留、6位标志位、紧急指针、选项数据(40个字节)
- 头部
- 有效字节(最小头部大小)20字节
- 最大长度60字节
-
5.2.3 连接管理
- 三次握手
- 两次不安全,四次没必要
- 假如第三次握手失败了,怎么办?
- 服务端若长时间没有收到最后一个ACK,服务端并不会超时重发SYN+ACK,而是直接发送重置连接到客户端。
- 四次挥手
- MLS时间:报文最大生存周期,一个数据包在网络中的最大生存时间,默认30s。
- 主动关闭连接方在发送最后一个ACK后,进入TIME_WAIT状态,等待两个MSL时间。
- TIME_WAIT作用:保证ACK能够到达对端,防止最后的ACK丢失导致对端重发的FIN包请求对新起的相同地址端口连接造成影响。
- 因为最后一个ACK丢失之后或因为网络状况不好导致在报文最大周期之内,对端没有收到ACK,因此重新发送FIN请求。
- 假如没有这个等待时间,而是直接重新启动程序。就有可能会接收到这个重发的FIN包对新连接造成的影响。
- 两个MSL时间
- 第一个:主动关闭方第一个ACK的最大生存周期
- 第二个:重发的FIN包在网络上的最大生存周期,如果主动关闭方在两个MSL时间后都没有收到重发的FIN请求,就可以关闭了。因为不管ACK是否成功,重发的FIN都会消失在网络中(超出最大生存周期)。
- TIME_WAIT作用:保证ACK能够到达对端,防止最后的ACK丢失导致对端重发的FIN包请求对新起的相同地址端口连接造成影响。
- 网络断开/对端关闭连接,程序如何快速判断连接已经断开?
- tcp内部有自己的连接监测机制,检测连接是否正常。
- 当隔了一段时间一直没有数据来往,发送一条包活信息,探测网络情况。操作系统在连续发送多次数据,没有ACK之后,认为连接断开。
- 发送端判断
- send向进程发送SIGPIPE异常信号,进程使用默认处理方式(退出进程)
- 接收端判断
-
当 recv 返回值< 0,socket 出错
-
当 recv 返回值> 0,成功,返回值为接受到的数据长度
-
当 recv 返回值= 0,表示对端关闭连接,连接断开,没有接受到数据
-
- tcp内部有自己的连接监测机制,检测连接是否正常。
- 三次握手
-
5.2.4 可靠传输
- 判断方法
- 确认应答机制(确定对方收到数据)
- 超时重传机制(若对方在一定时间内没有收到数据,重新发送)
- 校验和
- 序列号/确认序列号(保证数据有序)
- 确认序号=起始序号+数据长度
- 判断方法
-
5.2.5 提高传输效率
- tcp为了保证可靠传输,牺牲了传输性能。针对整体性能下降的挽救方法:
- 滑动窗口机制:连续发送窗口大小的数据 -> 压缩等待时间(一次发送多条数据)
- 快速重传
- 若接收到后序数据,但是前边数据丢了,则连发3条重传请求
- 发送3条而不是1条原因
- 防止网络延迟,可能在发送三条数据的期间接收到数据,就不需要重传了。
- 快速重传
- 延迟应答机制:集中等待时间、保持最大窗口(保持最大吞吐量)
- 拥塞窗口机制:探测网络状况,防止一开始大量丢包。拥塞窗口(发送方维护的窗口大小), 先发送较小的数据,当网络情况良好时,发送数据的大小按照指数增长。达到阈值后,增长速率减缓。一旦产生丢包状况,立即下降到最低,从头开始。
- 捎带应答机制:尽量避免无必要的数据传输。若接下来需要发送数据,就将ACK标记位置1,放到数据中共同发送。
- 滑动窗口机制:连续发送窗口大小的数据 -> 压缩等待时间(一次发送多条数据)
- tcp为了保证可靠传输,牺牲了传输性能。针对整体性能下降的挽救方法:
-
5.2.6 面向字节流
- 收发灵活,但是会造成粘包问题
- 粘包问题
- 字节流发送数据会将字节流数据先放到缓冲区中,等待数据大小超过缓冲区,然后一次发送。对端接收的时候有可能就将多条数据当做一条数据接收完毕进行处理。
- 产生原因
- 字节流数据没有明显边界
- 解决方法
- 数据定长
- 特殊字符间隔
- TLV格式(常用)
- 定义结构体:struct{uint8_t type; uint64_t len; char val[0];}
- type:发送数据类型
- len:发送val的长度
- 定义结构体:struct{uint8_t type; uint64_t len; char val[0];}
-
6. 网络层
负责地址管理与路由选择
发送数据时,数据不是直接发送到对端电脑上,需要经过很多路由器进行转发。转发的过程中涉及地址管理及路由选择。
-
6.1 IP协议
-
协议版本、头部长度、8位TOS字段、数据报长度、标识符、标志位、片偏移(13位)、生存周期TTL(网络中数据包所能经过的一个路由器条数,默认128)、协议、校验和、源ip、目的ip、选项、数据
-
-
6.2 地址管理
-
整个网络是由无数个局域网组成
-
假如路由器随意给主机分配IP地址,则有可能造成IP地址冲突(相邻两个网络的IP地址冲突),因此需要将地址的分配管理起来。
-
tcp因为在传输层会进行数据分段,将数据分解成合适的大小,因此在网络层基本不会出现数据分片操作;
-
udp因为在传输层没有数据分段的功能,所以当udp数据包的大小加上ip头长度超过MTU大小,则需要在网络上进行数据分片。
-
MTU:最大传输单元,当前主机一次性最大能发送多少字节的数据。
-
-
6.2.1 网段划分
- 网络号
- 每个路由器组建子网的时候使用一个标识能够区分网络,并且相邻的两个网络不能具有相同的网络标识。给子网中的主机分配地址的时候,按照网络标识来进行分配,把这个网络的表示称为网络号。每个IP地址都需要包含所在网络的标识。
- 主机号
- 路由器需要对子网中的主机地址进行管理,为每一个主机也分配一个标识,在子网中唯一标识主机,这个标识称为主机号。
- 每个局域网中都有两个特殊地址
- 主机号全为0:局域网的网络号,表示这个子网。
- 主机号全为1:局域网的广播地址。套接字是由UDP广播,TCP在传输层没有实现广播(需要用户应用层实现)
- 127.0.0.1本地虚拟回环网卡,用于本地的网络回环测试。防止因网卡问题导致测试失败。
- 将IP地址划分为两个部分:网络号(前24位)+主机号(后8位)
- 划分方式
- 早期
- A类
- B类
- C类
- 现在
- 由于早期的划分方式比较粗糙,所以引入了CIDR方案,在该方案中引入了一个字段叫子网掩码。
- 早期
- 路由器的IP:网关地址
- 当主机连上某个路由器后,主机UDP广播,将数据发送至整个网络中,根路由器相连发送给路由器。路由器将IP地址、网关地址以及子网掩码返回给主机。
- 子网掩码
- 数据类型:uint32_t
- 功能:通过IP地址计算网络号(子网掩码与IP地址相与 = 网络号)、计算子网中主机号数量
- 每个路由器上都有两个网卡
- WAN口:与上层通信,只能有一个
- LAN口:跟本地局域网通信,可以有多个
- 私网地址/公网地址
- 组建私网(局域网)时,不能随意使用网络号。因为一旦随意使用,有可能造成分配的IP地址与公网地址冲突。
- RFC1918规定能够用于组建私网的网络号只有:
- 172.16.*.*~172.31.*.*
- 10.*.*.*
- 192.168.*.*
- 网络号
-
7. 链路层
负责相邻设备之间的数据帧传输(两台主机与之间路由器的传输选择)
-
7.1 MAC地址
- MAC地址用来识别数据链路层中相连的节点;
- 长度为48位(6个字节)一般用16进制数字加上冒号的形式来表示(例如: 08:00:27:03:fb:19)
- 在网卡出厂时就确定了, 不能修改。MAC地址通常是唯一的(虚拟机中的MAC地址不是真实的MAC地址, 可能会冲突; 也有些网卡支持用户配置MAC地址)
- 主机获取相邻设备的ip地址
-
7.2 ARP协议
- 介于网络层与数据链路层之间的协议
- 功能:获取相邻设备的MAC地址
- 协议格式
- 以太网目的地址、以太网源地址、帧类型、硬件类型、协议类型、硬件地址长度、协议地址长度、发送端以太网地址、发送端IP地址、目的以太网地址、目的IP地址
- ARP网络攻击
- 局域网的欺骗攻击
- 黑客连接到主机,当主机为了获取下一个路由器的MAC地址,广播ARP数据包。黑客收到ARP数据包后,回复ARP响应,获取他人数据。
- 每次发送数据都获取MAC地址,效率太低。因此,当获取到相邻设备的MAC地址后,会在计算中做一个缓存。但是,这个缓存保存的时间不会太长(ARP协议通过IP地址获取MAC地址,现在IP地址大多都是DHCP自动分配,如果断网重连后,IP地址可能会发生改变,原先的地址有可能会被其他人使用,导致MAC匹配错误)。
-
7.3 以太网帧格式
- 目标MAC地址(6个字节)、源MAC地址、数据包类型、数据、校验和
- 源地址和目的地址是指网卡的硬件地址(也叫MAC地址), 长度是48位,是在网卡出厂时固定的。
- 帧协议类型字段有三种值,分别对应IP、ARP、RARP。
- 帧末尾是CRC校验码。
- 目标MAC地址(6个字节)、源MAC地址、数据包类型、数据、校验和
-
7.4 MTU 最大传输单元
- MTU=IP头大小+UDP/TCP头长度+数据长度
- 假如MTU=1500,使用UDP协议,数据最大长度为1500-20(IP头长度最小为20)-8=1472
- 7.4.1 MTU对UDP的影响
- 因为UDP在传输层不会分包,因此可能在网络层进行数据分片。若分片后,进行传输的时候,有任意一个数据分片出错,将会导致整个UDP数据包都被丢弃(UDP不会重传 -> 直接丢包)。因此,一盘情况下,在使用UDP传输数据时,会将UDP的数据包在应用层分为大小不超过最大传输段(1472)大小。
- 7.4.2 MTU对TCP的影响
- TCP在传输层建立连接时,会与对方进行协商,协商最大数据段大小(MSS=MTU-IP-TCP 1460),取双方协商中最小的一个进行传输层的数据分段。意味着TCP发送的数据在网络层基本不会出现数据分片。
- 为什么不用IP地址
- 用IP地址,需要使用网络层协议,有源地址和目的地址,当将目的地址改为路由器地址,路由器不知道将数据传给谁。需要多出一个字段,来标记发送给谁。
8. 其他重要协议及技术
-
8.1 DNS 域名解析系统
- 从域名映射到IP的系统
- 根域名服务器
- 全世界13台
- 作用:容灾处理、分摊压力
- 顶级域名服务器
- .com 商业域名服务器
- .org 公益性组织
- .net
- .gov 政府
- 面试:
- 浏览器中,键入url,按下回车都发生了哪些事情?2.26图
- 1. 域名解析
- 首先查看本机的hosts文件。不存在,向域名解析服务器发起请求->发送到运营商域名服务器,找到层层返回。没找到,向根域名服务器发起请求。没找到,请求顶级域名服务器。没找到,请求baidu二级域名服务器。找不到,请求三级...实在找不到,报错;找到,层层返回。
- 2. 组织HTTP请求
- HTTP协议格式
- 3.传输层TCP
- TCP协议及特性
- 4.网络层
- IP协议、地址管理、路由选择
- 5.链路层
- 以太头格式、ARP协议、MTU
- 1. 域名解析
- 浏览器中,键入url,按下回车都发生了哪些事情?2.26图
-
8.2 ICMP协议
- 一个网络层协议,使用IP地址
- 功能
- 探测网络是否联通
-
8.2.1 ping 命令
- 使用ICMP协议探测网络的命令ping
- ping的是域名而不是url
- 功能
- 验证网络的连通性
- 统计响应时间和TTL(IP包生存周期)
- 面试
- ssh使用22号端口、ftp使用21号端口,ping命令使用端口?
- ping命令使用的是ICMP协议实现,ICMP是网络层协议,端口是传输层协议的东西,涉及不到端口。
- ssh使用22号端口、ftp使用21号端口,ping命令使用端口?
-
8.2.2 traceroute 命令
- 基于ICMP协议实现
- 打印出可执行程序主机到目标主机之前经历多少个路由器。
-
8.3 NAT
- 引入
- 解决IP地址不够用的问题
- 功能
- 负责网络层的地址替换
- 能够将私有IP和全局IP相互转换
- 数据发送到路由器,路由器使用ANG服务将网络层源IP地址改为自己的WAN口地址,发送至上层。
- 回复数据时,路由器怎么知道是给那个主机的?
- 需要有映射关系 NAPT技术
- 使用IP+port关联关系
- 需要有映射关系 NAPT技术
- 负责网络层的地址替换
- 代理与NAT的区别
- NAT基于网络层服务,进行网络层的地址替换,并且一般部署在网络出口处(路由器)、防火墙等硬件设备。
- 代理是一个应用程序,是应用层的东西。运行部署在服务器上,代理服务器可以使用在广域网、局域网、也可以跨网,部署在服务器上。
- NAT缺陷
- 依赖转换表,有诸多限制
- 使用主机IP地址上网,没上网前,找不到虚拟机。无法外部向内部链接。
- 引入