计算机网络-小林coding-基础篇
本系列笔记为作者在跟随小林coding学习的时候做的笔记。感谢小林大大。加上自己的笔记
TCP/IP 网络模型有哪几层?
TCP/IP 网络分 4 层:应用层,传输层,网络层和网络接口层
ISO为7层,传统网络架构为5层,将数据链路层的物理层分离了出来单独作为一层。
传统网络分层为5层:应用层,传输层,网络层,数据链路层和物理层
附上网络协议层级图
键入网址到网页显示,期间发生了什么
HTTP
浏览器解析 URL字符串: 协议类型://域名或者IP:端口号/文件路径
端口号省略时默认是协议对应的默认端口,比如http是80
没有路径名则访问index.html或default.html
根据这些信息生成 HTTP 请求消息
DNS查询
应用层,传输层,网络层和网络接口层发送之前需要查询服务器域名对应的 IP 地址。
域名由.
分割,越靠右的位置表示其层级越高。域名的层级关系类似一个树状结构:
- 根 DNS 服务器(.)
- 顶级 DNS 服务器(.com)
- 权威 DNS 服务器(server.com)
首先是查询浏览器缓存和操作系统缓存以及host解析,没查到再进行dns域名解析
域名解析的工作流程
- 客户端发出 DNS 请求给本地设置的 DNS 服务器地址
- 本地域名服务器查询缓存,找到 www.server.com,则直接返回 IP 地址。否则本地 DNS 会去问它的根域名服务器
- 根 DNS 返回给本地域名服务器 .com 顶级域名服务器地址
- 本地域名服务器和返回的服务器地址重复2,3步,直到找到权威域名服务器。
- 权威域名服务器直接返回IP给本地域名服务器
- 本地域名服务器将IP返回给客户端
通常客户端到域名服务器是不可靠无连接的UDP通信,域名服务器之间使用可靠有连接的TCP通信进行迭代查询
操作系统协议栈
获取 IP 后,操作系统中的协议栈处理和发送数据包(传统网络架构中的传输层到数据链路层。物理层由网卡驱动接管)。
应用程序(浏览器)通过调用 Socket 库,来委托协议栈工作。
TCP
源端口号和目标端口号寻址
包的序号解决包乱序的问题
状态位:改变协议状态。
窗口大小做流量控制
协议规定了自己的拥塞控制行为
TCP 传输数据之前,要先三次握手建立连接
查看 TCP 的连接状态:netstat -napt
MSS:TCP包载荷的最大长度
MTU:一个IP包的最大长度,一般为1500字节
IP
源地址 IP 和 目标地址 IP
传输层协议的协议号
路由数据包时根据路由表规则,来判断哪一个网卡作为源地址 IP
route -n 命令查看当前系统的路由表(推荐ip系列的命令 ip routes)
路由数据包流程:路由表从上往下将包目的ip和掩码与运算,结果和目的网段相同就匹配上,使用匹配的网卡(端口)进行转发。通常最后一个条目的目的网段和子网掩码都是0.0.0.0,称为默认网关,当上面的都不匹配的时候就发送到这个网卡接口,该条目的Gateway就是默认网关ip地址。发送出数据包时,当Gateway为0.0.0.0时表示该网段跟主机是直连的,链路层将目的ip对应的MAC作为链路层包头的MAC,否则使用Gateway 的MAC。
MAC
MAC 包头里需要发送方 MAC 地址和接收方目标 MAC 地址,用于两点之间的传输
MAC 包头的协议类型只使用:0800 : IP 协议;0806 : ARP 协议
发送方的 MAC 地址是在网卡生产时写入到 ROM 里的,只需要将这个值读取出来写入到 MAC 头部。
接收方的 MAC 地址需要 ARP 协议来获取。
ARP 协议会在以太网(局域网)中广播ip地址,接收到回应后将MAC写入ARP缓存(缓存时间为几分钟)
发包时:
- ARP 缓存已经保存了对方的 MAC 地址,直接使用 ARP 缓存中的地址。
- ARP 缓存中不存在对方 MAC 地址时,发送 ARP 广播查询。
arp -a查看 ARP 缓存的内容
网卡
我们需要将数字信息转换为电信号,才能在网线上传输,由网卡负责。网卡驱动程序控制网卡。
网卡驱动获取网络包之后,会将其复制到网卡内的缓存区中,接着会在其开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列。
- 起始帧分界符是一个用来表示包起始位置的标记
- 末尾的 FCS(帧校验序列)用来检查包传输过程是否有损坏
交换机
将网络包原样转发到目的地。也称为二层网络设备(即传统网络架构中的数据链路层,不涉及网络层及以上数据包的修改)
交换机的包接收操作:交换机接收电信号,将电信号转换为数字信号,通过包末尾的 FCS 校验错误,如果没问题则放到缓冲区,根据 MAC 地址表查找 MAC 地址,然后将信号发送到相应的端口。当 MAC 地址表找不到指定的 MAC 地址,将包转发到除了源端口之外的所有端口。
交换机的 MAC 地址表主要包含两个信息:一个是设备的 MAC 地址,另一个是该设备连接在交换机的哪个端口上。
对于主机而言,只有目的地址跟自己的MAC一致包才接收,忽略其他包
广播地址(全1):
- MAC 地址中的 FF:FF:FF:FF:FF:FF
- IP 地址中的 255.255.255.255
路由器
路由器是基于 IP 设计的,俗称三层网络设备(即传统网络架构中的网络层),路由器的各个端口都具有 MAC 地址和 IP 地址
路由流程见上面IP层
路由器的端口都具有 MAC 地址,只接收与自身地址匹配的包,遇到不匹配的包则直接丢弃
互相扒皮 —— 服务器 与 客户端
逐层协议分析包头。链路层接收和自己的 MAC 地址符合的包。网络层接收和自己的IP地址符合的IP包。根据IP头读取传输层协议。TCP会检查首部校验和序列号并返回ACK,UDP只检查首部校验和。读取传输层端口号,并将传输层载荷发送给进程。
Linux 系统是如何收发网络包的?
网络模型
OSI7层,传统5层,TCP/IP4层
Linux 网络协议栈
- 应用程序需要通过系统调用,来跟 Socket 层进行数据交互;
- Socket 层的下面就是传输层、网络层和网络接口层;
- 最下面的一层,则是网卡驱动程序和硬件网卡设备;
Linux 接收网络包的流程
当网卡接收到一个网络包后,会通过 DMA 技术,将网络包写入到指定的内存地址,也就是写入到 Ring Buffer,缓存满了就会触发中断唤醒数据接收的服务程序,然后 poll 的方法来轮询数据
硬件中断处理函数:先「暂时屏蔽中断」,表示已经知道内存中有数据了。发起「软中断」,然后恢复刚才屏蔽的硬件中断。
硬件中断处理函数做的事情很少,主要耗时的工作都交给软中断处理函数了。
软中断的处理:当 ksoftirqd 内核线程收到软中断后,就会来轮询处理数据。ksoftirqd 线程会从 Ring Buffer 中获取一个数据帧,用 sk_buff 表示,从而可以作为一个网络包交给网络协议栈进行逐层处理。
发送网络数据的时候,涉及几次内存拷贝操作?
第一次,调用发送数据的系统调用的时候,内核会申请一个内核态的 sk_buff 内存,将用户待发送的数据拷贝到 sk_buff 内存,并将其加入到发送缓冲区。
第二次,在使用 TCP 传输协议的情况下,从传输层进入网络层的时候,每一个 sk_buff 都会被克隆一个新的副本出来。副本 sk_buff 会被送往网络层,等它发送完的时候就会释放掉,然后原始的 sk_buff 还保留在传输层,目的是为了实现 TCP 的可靠传输,等收到这个数据包的 ACK 时,才会释放原始的 sk_buff 。
第三次,当 IP 层发现 sk_buff 大于 MTU 时才需要进行。会再申请额外的 sk_buff,并将原来的 sk_buff 拷贝为多个小的 sk_buff。