包是由头部和数据两部分构成的,头部包含目的地址等控制信息(当作快递面单),头部后面就是数据部分,包括了要发送给对方的数据,也就相当于快递里面的货物。

  1. 发送方网络设备负责创建包,创建包的过程就是生成含有正确控制信息的头部,然后再附加上要发送的数据。
  2. 包被发往最近的网络转发设备
  3. 转发设备判断接下来该往哪里发
    1. 使用路由表
    2. 记录了每一个地址对应的发送方向,按照头部里记录的目的地址在表里进行查询,并根据查询到的信息判断接下来应该发往哪个方向。
  4. 转发给下一个设备,直到到达接收方的网络设备。

发送

转发操作

TCP/IP头部中包含MAC头部+IP头部

  1. 发送方将目的地址写入IP中
  2. 找到下一个路由器的位置
  3. IP协议委托以太网协议将包传输过去
  4. IP协议会查找下一个路由器的以太网地址,并将这个地址写入MAC头部中
  5. 发送

image.png
IP头部:

IP   以太网 - 图2

MAC头部:
IP   以太网 - 图3

源地址、目的地址:48bit
类型:16bit,常用的是0800代表IP类型,0806代表ARP类型

ARP

从IP地址获取MAC地址

  1. 先查询ARP缓存
  2. 发送广播,询问某个IP地址对应的MAC地址
  3. 进行回答

ARP缓存在一段时间后会失效,是为了防止IP地址变化时候ARP内容和现实发生差异。

接收

网卡会将网络包交给TCP/IP协议栈

  1. 检查IP头部,查看接收方IP地址
    1. 如果不是自己的IP地址,那么IP模块通过ICMP消息将错误告知给发送方
  2. 接收方IP地址正确,将包接收下来
  3. 如果包是分片的,将其还原位原始的包
  4. 交给TCP模块
  5. TCP根据IP的接收方和发送方IP地址,以及TCP头部中的接收方和发送方端口号来查找对应的套接字

以太网

image.png
网卡驱动从IP模块取出包后,会将其复制给网卡内的缓冲区中,然后向MAC模块发送包的命令

  • MAC模块会将包从缓冲区取出,并在开头加上报头和起始帧定界符,在末尾加上帧校验序列FCS

接收

  1. 在集线器模式的半双工以太网中,一台设备发送的信号会到达所有的设备,所以对于所有设备来说,把自己接收到的信号,不论是不是自己的,都接收过来
  2. 检查FCS和自己计算出的是不是一样的,如果不一样,丢弃
  3. 如果FCS没有问题,那么下一步查看MAC头部中接收方MAC地址和网卡在初始化时分配给自己的MAC地址是否一致,判断这个包是不是给自己的;是就保留,不是丢弃
  4. 如果是发给自己的,包放入缓冲区
  5. 使用中断通知计算机
  6. 计算器中断后取出网卡的缓冲区中的收到的包,通过类型字段检查协议类型,根据以太类型将包交给对应的协议栈

路由器转发

路由器在转发包时,首先会通过端口将发过来的包接收进来
转发模块会根据收到的包的IP头部中记录的接收方IP地址,在路由表中进行查询,判断转发目标
然后转发模块将包转移到目标对应的端口,端口再按照硬件的规则将包发送出去,也就是转发模块委托端口模块将包发送出去。

路由器接收包

  • 路由器端口都有自己的MAC地址,只接受与自身地址相匹配的包,遇到不匹配的包则直接丢弃。
  • 完成包的接收以后,路由器就丢弃包开头的MAC头部,MAC头部的作用就是将包送到路由器,接收方的MAC地址就是路由器端口的MAC地址
  • image.png
  • 匹配地址的时候,路由器需要直到网络号的比特数,因此路由表还有一系列子网掩码
    • 路由器忽略主机号,只匹配网络号(根据子网掩码进行匹配)
    • 路由聚合
      • 多个子网合并成一个子网,子网掩码会发生变化
      • image.png
  • 按照最长匹配原则进行查找,如果有多个最长匹配记录,选择跳数最小哪个
    • 如果无法匹配且没有默认路由,路由器丢弃这个包,并发送ICMP消息告诉给发送方
    • image.png默认路由子网掩码0000,即匹配比特数为0,默认路由
  • 找到了转发端口,包被转发到输出端口,并最终转发出去,但还有做些工作
    • 更新IP头部的TTL,如果值变成了0,就表示超过了有效期,包被丢弃(防止死循环)
  • 分片:(与TCP分片的区别是TCP分票是在将数据装到包之前进行的)
    • 得到输出端口的MTU(最大包长度),最大长度减去头部就是可以传输的数据大小
    • 如果头部规定不能分片,只能丢弃这个包,通过ICMP告知对方
  • 发送
    • 通过ARP查询下一个接收方MAC

NAT地址转换

基本原理:
在转发网络包的时候对IP头部中的IP地址和端口号进行改写。
image.png