TCP/IP读书笔记(4) IPv4和IPv6 路由选择

网络层是位于链路层之上,TCP/IP模型中网络层的核心协议是IP协议(Internet protocol)。

目前主流的IP协议是IPv4(Internet protocol version 4),但是IPv6(Internet protocol version 6)会是趋势。

IP协议提供不可靠,无连接的数据传输服务,它只负责接受数据包,转发数据库,不维护两端的连接状态。IP层唯一的校验是,IPv4规定通过在路由节点计算校验和来确保IP数据报头是正确的,但是IPv6的时候已经没有了。因为这些本就不该是IP层应该考虑的事情。

IP协议定义了网络层数据包的格式,和如何转发数据包。

IP数据包的格式

IPv6是对IPv4的一个最小扩展,只修改了IP头部,IPv4和IPv6头部数据包的格式,参考TCP/IP卷一第二版第182页。

无论是IPv4还是IPv6,数据包包括两部分:IP头部、IP数据,头部都提供了

  • 版本号 IPv4这个值是4,IPv6是6
  • 包长度 这个数据包的长度
  • 源IP的地址 发送端的IP地址,在IPv4中占4字节,IPv6中占16字节,局域网内传输时通常不会改变,但是如果使用了nat的话,会被修改。
  • 目的IP的地址 完全同上
  • 上层协议号 标识上层协议,列如TCP,UDP,VRRP等。在v4和v6中都只有8位字节,也就是最多256种上层协议。
  • 数据包生存时间 为了防止一个数据包被永远转发下去,需要需要设置:这个数据包被路由器发送“生存时间“次数后如果还是没到达目的地就将它抛弃,每个路由器转发数据包之后都会将生存时间-1,直到它变成0就不再转发。
  • 服务类型 主要是运营商做qos使用,IPv4允许选择置3位优先级级别(现已被忽略),4位TOS(服务类型),包括4种类型:最小时延,最大吞吐率,最高可靠性。IPv6提供8位的Traffic Class(通信级别),类似的作用。

IPv6和IPv4头部的一些主要区别在于:

  • IPv6头部中没有校验和,路由器不需要对每个达到的数据包计算校验和,判断头部是否正确,提高速度。
  • IPv4可以设置分片标识,这里牵扯到上一篇笔记中提到的MTU的概念,如果一个数据包长内容长1400字节又允许分片,而当前路由器的MTU是500,那就会将它分成500,500,400的三部分发出去,如果不允许分片,这个数据包会被丢弃,并产生一个错误。
  • IPv6头部中没有分片标识,它只允许数据发送方决定对数据包进行分片,中间路由器不可以分片,如果发送方的分片不合适,中间路由器会丢弃数据。
  • IPv6支持的服务类型更多,详细可以看思科的这篇文章实现服务质量策略与DSCP

为什么IPv4中传输层,网络层,链路层都有校验和,IPv6网络层不设置校验和?

链路层的校验只能保证数据从一个路由器到另一个路由器中间没有出错(绝大多数情况下能保证)。

数据包到了路由器之后,路由器会把这个数据包拆开,根据下一跳的地址,设置新的链路层头部的目的地址,crc校验值,IP首部的的ttl值,甚至可能还会对数据包进行分片,这样修改的更多了,如果在路由器处理的过程中这个数据出错,那么链路层的校验是发现不了错误的。

所以要保证数据包从发送端到目的地址都没有出错,还需要传输层有自己的校验。
至于网络层的校验,现在看来确实是没必要的,IPv6网络层为了提高速度,已经不再校验。
IPv6中间路由器也不会对数据包进行分片

路由选择

路由转发,ip层通过路由器,将数据从源目的地址发送到目的地址的功能,没啥好说的,大学都很清楚了。
路由转发不仅仅是路由器的功能,服务器也有路由转发,在linux机器上执行route -n可以看到类似下图的结果

当ip层发送一个数据包时:

  • 它会根据目的ip地址,在路由表中搜寻完全匹配的项
  • 如果搜寻不到,搜寻网络地址(cidr中的地址)匹配的项
  • 如果搜寻不到,搜寻默认地址
  • 将数据包从搜寻到的项中的接口对应的设备发出

需要注意的是,使用静态路由时,路由表在以下几种情况可能会被修改:

  • 路由器发现这个数据包不应该被发送给它(路由器r2将数据发给r1,r1发现它需要将数据发给r2)时,产生ICMP重定向错误,告诉发送方直接把数据发给r2
  • 主机或者网卡启动时发送三份路由请求报文,如果收到,就停止发送,根据报文内容更新路由表。可能之前网络是通的,启动了一个网卡之后,默认路由被更改,部分网络不再联通
  • 链路断开时,部分路由项被移除

另外,服务器默认不转发不是由它产生的数据包,可以将网卡配置成混杂模式,当做路由器使用,转发不属于它产生的数据包。

最新文章

  1. spring.xml中的配置
  2. Sql 中text类型字段判断是否为空
  3. SQLServer 脚本测试
  4. 关于原生的Javascript
  5. JSP 相关试题(四)
  6. [工作积累] Google Play Game SDK details
  7. android-exploitme(二):安装apk熟悉测试环境
  8. php 调试工具及学习PHP垃圾回收机制了解引用计数器的概念
  9. composer的安装
  10. as3.0服务端FMS软件常用的方法与属性参考示例
  11. 自定义Window进入和退出效果(转)
  12. Delphi代码中嵌入ASM代码(简单明了)
  13. 有关Android存储的相关概念辨析
  14. SQL零星技术点:SQL中转换money类型数值转换为字符串问题
  15. 解决 Popup 位置不随窗口移动更新的问题
  16. Linux服务器运维基本命令
  17. 在ibatis中时间段查询完整代码
  18. 根据运算符优先级解析SQL规则表达式
  19. Mybatis 与hibernate
  20. 总结函数open与fopen的区别

热门文章

  1. Mybatis集成到spring boot
  2. JDK自带的Timer类
  3. .NET框架(转)
  4. 不干胶打印机 www.bgjdyj.com
  5. mongodb备份恢复,数据导入导出
  6. Windows实用命令
  7. dubbo 线程池
  8. shared_ptr模版推导的问题
  9. elasticsearch例子(crud + 分页)
  10. java 实现websocket的两种方式