linux高性能服务器编程 (二) --IP协议详解
第二章 IP协议详解
什么是IP协议:IP 协议是TCP/IP协议族的动力,它为上层提供了无状态、无连接、不可靠的服务。
IP 头部信息:头部信息会出现在每一个IP数据报上,便于记录IP通信的源端IP地址,目的端IP地址,指导IP分片和重组,以及指定部分通信行为。
IP 数据报的路由和转发:除目标机器之外的所有主机和路由器上。它们决定数据报是否应该转发和如何转发。
无状态:即每次的IP数据报发送、传输和接收都是相互独立的,没有上下文关系。缺点:无法处理乱序和重复IP数据报;优点:简单、高效。
无连接:IP通信双方都不长久的维持对方的数据,所以每次发送数据的时候都需要带着指定对方的IP地址。
不可靠:IP协议不能保证IP数据报准确地到达接收端。(如果某个路由器发现IP数据报在网络上存货时间过长,就会弃之。会返回一个ICMP的错误消息给发送端)
IPv4的头部结构:
ipv4的头部信息从图片上可知,IP头部长度通常固定为20字节。其中重要的 16位总长度,它记录了IP数据报文的整个长度,最大长度可设置为65535字节,但是由于设置了MTU长度限制,所以,一旦IP数据报内容长度大于MTU的设置将进行分片传输。16位标识值是其默认的标识号,最开始是随机生成的,每发送一个数据报其值就会+1,所以对于分片操作,这个值就会被复制到每一个分片数据报的头部用来标识其分片是同一个数据包。3位标志字段的第一位属于保留字段,第二位标识禁止分片(DF),第三位标识多个分片(MF)。如果这个数据报分片了,那么除了最后一个分片其他分片3位标志要设置为1. 13位片偏移 是说明如果数据报偏大需要进行分片,那么分片的需要一个前后位置的区分,这个时候就需要偏移值去设置分片的位置,才能保证后面的IP分片拥有自己的偏移值。8位生存时间TTL就是数据报在到达目的地所经过的路由器跳数。虽然IP数据报请求过来经过广播转发路由器,但它不是一个死循环,它也是需要一个介质控制跳动的个数,而这个值就是它的介质。16位头部校验,是为了监测IP数据报在路由器转发的过程中是否有数据损失,其值是发送端设置的。当数据报到达目的地的时候,接收端使用CRC算法对数据进行校验。而32位源端IP和目的地IP地址则是发送端的IP地址和到达目的地的地址,所以这个在传输的过程中是不会变的。
IP分片
举个例子如上图:对于以太网帧的MTU是1500字节。对于IP数据报1501个字节来说就需要进行分片转发路由。对于第一个分片需要将其头部3位标志设置(mf)置为 1,而将最后一个 (mf)置为 0 。对于第一个分片去掉IP头部固定为长度为20个字节,那么剩余可存放的字节数为1480个字节。只要满足IP数据报的长度为1500字节即可,对于IP数据报1501个字节那么它的第二个数据报的长度为应该为21个字节(因为包含固定IP头部20个字节)。从图片中可了解,原始的IP数据报将头部数据复制成了第一个分片的头部信息,而第二个分片则不需要ICMP等多余的头部的信息(因为没必要在重复)。那么对于IP都是无连接、无可靠、无状态的性质来说,分片传递到目标端它们也是可以组合在一起的,这就通过上文描述的16位标识取组合在一起。那么如果第二个分片先到达目的地,也是可以和第一个分片组合在一起的,因为对于分片来说事先都已经设置好前文所说的13位片偏移,通过偏移值可以找到该分片应该处放的位置,直到遇到衔接的分片就会进行分片组合。
IP路由
上文已经说了IP数据报的分片,将一个个小小的分片进行路由转发送达到目的地。没错,那么IP协议是如果进行选路由的呢?首先我们需要了解一下IP模块的工作流程。
根据上图从右->左的方式开始讲解。当IP模块接收到来自数据链路层的IP数据报时,首先通过CRC校验一下头部数据是否有损失,如果损失则发送一个ICMP的错误消息。如果ok则验证IP数据报的头部是否设置了源站选路,如果设置了则进行数据报转发流程,如果没有则发送给本机的数据报验证。在本机的数据报验证处需要判断是否是发送给本机的某个IP地址、如果不是发送给本机的那就是需要发送到上层网络层的某个IP地址则也调用数据报转发子模块来处理该数据报。而在数据报转发处需要验证该数据报是否允许转发,如果不允许转发则丢弃。否则会对该数据报进行一些操作,然后将它交给IP数据报输出子模块。
这里略过转发路程,IP模块实现数据报路由的核心数据结构是路由表,这个表按照目标地址IP分类,同一类型的IP数据报将被发往相同的吓一跳路由器。IP的路由机制共分为三个步骤:1)查找路由表中和数据报的目标IP地址完全匹配的主机地址,如果找到就使用该路由表项,否则转向步骤2。2)查找路由表中和数据报的目的IP地址具有相同网络ID的网络IP地址,即是同一网段的IP地址,如果找到则使用该路由表项,否则转向步骤3。3)选择默认路由,通常意味着下一跳路由是网关。
路由表必须能够更新,才能让IP模块准确高效的转发数据报。路由表的变更可以通过手动变更,或者通过route命令变更,对于测试来说是常用的手段。但是对于大型路由器。它们通常是动态或自动更新的,主要由 BGP (边际网关协议) RIP (路由信息协议) OSPF 等协议来发现路径,并更新自己的路由表。
除了发送给本机的IP数据报都会走到数据报转发子模块来处理。如果该数据报允许转发那么数据报转发子模块将对期望转发的数据报执行如下流程:1)检查数据报头部的TTL值,如果TTL值已经是0,则丢弃该数据报。2)查看数据报头部的严格源路由选择选项,如果该选项被设置,则检测数据报的目标IP地址是否是本机的某一个IP地址,如果不是则发送一个ICMP源站选路失败报文给发送端。3)如果有必要,则给源端发送一个ICMP重定向报文,以告诉它一个更合理的吓一跳路由器。4)将TTL值减 1.5)处理IP头部选项。6)如果有必要,则执行IP分片操作。
从上图上可看到,还有一个ICMP重定向报文。在特定的情况下,当路由器检测到一台机器使用非优化路由的时候,它会向该主机发送一个ICMP重定向报文,请求主机改变路由。路由器也会把初始数据包向它的目的地转发。发生ICMP重定向通常有两种情况:1)当路由器从某个接口收到数据还需要从相同接口转发该数据时。2)当路由器从某个接口到发往远程网络的数据时发现源ip地址与下一跳属于同一网段时。
linux高性能服务器编程 (二) --IP协议详解的更多相关文章
- linux高性能服务器编程 (三) --TCP协议详解
第三章 IP协议详解 TCP协议是TCP/IP协议族中的另外一个重要的协议,与IP协议相比,TCP协议更高进应用层.一些重要的socket选项都和TCP协议相关.这一章主要从如下方面学习: 1)TCP ...
- Linux 高性能服务器编程——TCP/IP协议族
1 TCP/IP协议族体系结构 数据链路层: 职责:实现网卡接口的网络驱动程序,一处理数据在物理媒介(如以太网.令牌环等)上的传输. 常用协议:ARP协议(地址解析协议),RARP协议 ...
- Linux 高性能服务器编程——IP协议详解
1 IP服务特点 IP协议是TCP/IP协议族的动力,它为上层协议提供无状态.无连接.不可靠的服务. 无状态:IP通信双方不同步传输数据的状态信息,因此IP数据包的发送.传输和接收都是无序的. ...
- Linux 高性能服务器编程——TCP协议详解
问题聚焦: 本节从如下四个方面讨论TCP协议: TCP头部信息:指定通信的源端端口号.目的端端口号.管理TCP连接,控制两个方向的数据流 TCP状态转移过程:TCP连接的任意一 ...
- linux高性能服务器编程 (一) --Tcp/Ip协议族
前言: 在学习swoole入门基础的过程中,遇到了很多知识瓶颈,比方说多进程.多线程.以及进程池和线程池等都有诸多的疑惑.之前也有学习相关知识,但只是单纯的知识面了解.而没有真正的学习他们的来龙去脉. ...
- 服务器编程入门(2)IP协议详解
问题聚焦: IP协议是TCP/IP协议族的核心协议,也是socket网络编程的基础之一.这里从两个方面较为深入地探讨IP协议: 1,IP头部信息(指定IP通信的源端IP地址,目的端IP ...
- linux高性能服务器编程
<Linux高性能服务器编程>:当当网.亚马逊 目录: 第一章:tcp/ip协议族 第二章:ip协议族 第三章:tcp协议详解 第四章:tcp/ip通信案例:访问Internet 第五章: ...
- Linux 高性能服务器编程——Linux网络编程基础API
问题聚焦: 这节介绍的不仅是网络编程的几个API 更重要的是,探讨了Linux网络编程基础API与内核中TCP/IP协议族之间的关系. 这节主要介绍三个方面的内容:套接字(so ...
- Linux高性能服务器编程,书中的 shell 命令
记录<Linux高性能服务器编程>书里面讲解到的若干 shell 命令 arp 命令查看ARP高速缓存: [root@VM_0_10_centos heliang]# arp -a ? ( ...
随机推荐
- flyway.setBaselineOnMigrate(true);
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayWrappe ...
- Ubuntu 挂载硬盘命令介绍
版权声明:本文为博主原创文章,欢迎转载与采用. https://blog.csdn.net/HinstenyHisoka/article/details/71055656 新升级了Ubuntu 从16 ...
- Mybatis源码解析(三) —— Mapper代理类的生成
Mybatis源码解析(三) -- Mapper代理类的生成 在本系列第一篇文章已经讲述过在Mybatis-Spring项目中,是通过 MapperFactoryBean 的 getObject( ...
- spark任务在executor端的运行过程分析
CoarseGrainedExecutorBackend 上一篇,我们主要分析了一次作业的提交过程,严格说是在driver端的过程,作业提交之后经过DAGScheduler根据shuffle依赖关系划 ...
- Texture(ASDK)、ComponentKit、LayoutKit、YogaKit
YogaKit 最轻量,改动量最小,目的最纯粹,同时也最类似于使用 frame ,需要自己造一波在 UITableView 中使用的轮子(各类 frame 结果缓存方案).同类的备选方案是 FlexB ...
- 【python】多任务(1. 线程)
线程执行的顺序是不确定,可以通过适当的延时,保证某一线程先执行 基础语法 # 多线程的使用方式 import threading def test1():... # 如果创建Thread时执行的函数, ...
- MySQL数据库中字符串函数之left、right用法
语法 LEFT(str,len) Returns the leftmost len characters from the string str, or NULL if any argument is ...
- AI的自学题库-竞赛-基础知识
阿里云(天池): https://tianchi.aliyun.com/course?spm=5176.12281897.0.0.209439a9UwObn3 天池竞赛:https://tianchi ...
- 微信开发:"errcode": -1000,"errmsg": "system error"错误的解决办法
最近在微信开发使用微信公众平台接口调试工具时遇到错误. 错误再现:使用appid及appsecret在该测试工具中获取access_token,检查问题时,校验全部通过,但是无法获取access_to ...
- pip下载加速
安装pqi pip install pqi pqi回车 pqi ls pqi tuna pqi show pip install --upgrade pqi git链接 https://github. ...