也许你无数遍听过IP,但是晓得IP的运行原理吗?IP,是Internet Protocol Address的简写,一般翻译为互联网协议地址、或网际合同地址。每一台笔记本、每一步手机都有自己的IP。在联接互联网设备时,IP发挥着举足轻重的作用,那么它的运行原理到底是哪些?在本文中,淘宝中级程序员“我不想种粮”,将会为你剖开撒落地讲清楚!
一、TCP/IP网路模型:
TCP/IP网路模型分为4层,自下而上分布为链路层(又叫网络接口层)、网络层、传输层、应用层。
链路层:处理数据在媒介上的表示、传输以及与硬件交互的细节。
网络层:IP层负责IP数据报的路由转发,所有的TCP、UDP、ICMP和IGMP数据都通过IP数据报传输。网络层(IP)提供了一种尽力而为、无联接、不可靠的数据报交付服务,IP负责将IP数据报(又叫分组),放入数据链路层传输,负责分片和重组逻辑。
传输层:为端主机上运行的应用程序提供端到端服务,包括TCP和UDP。TCP提供了带流量控制、拥塞控制、有序、可靠的流交付,TCP须要处理丢包测量重传、重排序等IP层不处理的问题,TCP面向联接,不保留消息边界;而UDP提供的功能基本上没有赶超IP,不提供速度控制和差错控制,不保证可靠性,UDP只是提供一套端口号,用于复用、多路分解(即把收到的UDP数据报交给应用层对应程序处理)和校准数据完整性(只检错不纠错),UDP面向非联接,保留消息边界。
应用层:负责处理特定应用的细节,通常应用的实现都是基于TCP/IP或则UDP/IP。应用层与应用细节相关,与网路数据传输无关,而之下的三层(链路层、网络层、传输层)则对应用一无所知,但须要处理通讯的细节。
二、分层&协议对照:
网络分层实现了上层对下层透明,而下层借助了上层提供的能力。分层的另一个优点是合同复用,这种复用容许多种合同共存于同一基础设施之中,复用可以发生在不同层,并在每层都有不同类型的标识符分辨,用于确定信息属于那个合同,比如在链路层,链路层的数据帧(Frame)有一个协议标识符字段,用来标示链路层帧携带的合同是IP还是ARP,又例如在网路层,IP层的IP数据报的背部有一个8位合同数组,标识该IP数据报来自于TCP、还是UDP、亦或是ICMP、IGMP......
三、封装:
数据在发送端从上到下经过TCP/IP协议栈,应用层->TCP/UDP->IP->链路层,当某层的一个协议数据单元(PDU)对象转换为由底层携带的数据格式表示,这个过程称为在相邻低层的封装,即下层被封装对象作为不透明数据充当底层的Payload部份,封装是层层包裹的过程。
每层都有自己的消息对象(PDU)的概念,TCP层的PDU叫TCP段(segment),UDP层的PDU叫UDP数据报(Datagram),IP层的PDU叫IP数据报(Datagram),链路层的PDU叫链路层帧(Frame)。
封装的本质是将来自下层的数据看成不透明、无须解释的信息,经过本层的处理,在下层PDU的后面加上本层合同的腹部,有些合同是降低尾部(链路层),头部用于在发送时复用数据,接收方基于各层封装过程中降低腿部中的分解标识符执行分解。
具体到TCP传输数据而言,发送端的数据要经过4次封装,应用层数据经过TCP层的时侯,会降低TCP背部,产生TCP Segment,TCP背部中的端口号是该层的分解标识符;
经过IP层的时侯,会降低IP背部,产生IP Datagrame,IP背部中的合同类型数组是该层的分解标识符;
经过链路层的时侯,会降低以太网首部、尾部,产生以太网帧,帧背部中的以太网类型数组,可用于分辨IPv4(0x8000)、IPv6(0x86DD)和ARP(0x0806)。
四、分用:
数据抵达接收端(是目的机器),会经过从下到上经过TCP/IP协议栈,链路层->IP->TCP/UDP->应用层。经过链路层会剥离以太网首尾部,根据以太网类型数组,如果是IP Datagram则交给IP层;
经过IP层会消除IP背部,根据IP背部中的合同类型数组,交给TCP、UDP或则ICMP、IGMP;经过TCP/UDP层除去TCP/UDP背部,根据端口号,最终将数据还原取出交付给应用程序。
封装发生在发送方,拆封(还原)发生在接收方。
五、消息边界:
应用层将合同携带的数据写入消息,消息边界是两次写入操作之间的位置或字节偏移量,保留消息边界的合同(UDP)在接收方将能获得发送方的消息边界,而不保留消息边界的合同(TCP)在接收方将不能获得发送方的消息边界。
比如发送端通过UDP合同先后发送2个大小分别为100、200字节的消息,接收端通过UDP合同接收数据,将分2次分别接收到100、200字节的消息,但不保证接收100、200消息的先后次序;
而TCP是数据流合同,如果发送端通过TCP协议先后发送2个大小为100和200字节的消息,接收端会收到300字节数据,但每次接收返回的不一定是100、200字节消息,接收端遗失了发送端的消息边界。
六、网络地址:
IP地址用于IP层,IPv4的IP地址是32位整数,最多可以表示40亿多个IP地址,按8位一字节面试时让你说tcp协议,则分为4字节,每个字节是一个0~255的整数,所以可以表示abc.def.ghi.jkl的点分十进制格式,点分十进制和无符号32位整数可以很容易换算。
IPv4地址空间分成五大类,A、B、C类用于Internet时隙,D类地址供组播使用,E类地址保留。IPv4的32位又被界定为网路号和主机号,可以把网路号想像成到新村的邮政地址,而主机号想像成卧室号。
链路层使用48bit的MAC地址,ARP和RARP用于IP地址和MAC地址之间的互相换算。
七、应用程序编程插口:
操作系统通过提供编程插口(API)来支持应用程序的网路开发,目前最流行的API是套接字(Socket),也叫Berkeley套接字,Socket具象层坐落应用层跟传输层之间,提供创建、绑定、监听、连接、发送、接收、关闭等常用技巧。
八、Internet协议:
IP是TCP/IP协议族中的核心合同,为传输层提供IP数据报的交付能力,它负责将IP数据报从网路一端传递到另一端,实现数据转发。
IP的另一个作用是:在发送端,接收来自传输层的协议数据单元(PDU),添加IP首部封装为IP数据报,交给协议族的下一层:链路层。在接收端(包括中间路由器),接收来自链路层的PDU,去掉IP首部,根据IP首部中的合同类型,将数据分发给TCP、UDP或则其他。
IP只是完成分组交换(转发),如果你希望得到可靠性保证,IP会说:对不起,不归我管。发送一个IP数据报如同寄一个快件,只需把目的地寄件人写在快件上,快递公司会路由分发,但中间有可能丢件,丢了不管,而且到了,也不会有确认,一切随缘。
基于TCP/IP协议族建立的网路,可以分辨为端系统(两边的主机)和中间系统(中间路由器),端主机实现网路所有层,而路由器实现传输层之下的所有层,IP使用逐跳合同,IP之上的各层使用端到端合同。
九、路由器:
路由器工作于网路层,是IP层的核心设备,路由器有两个或两个以上的网路插口,用于联接两个或多个网路,负责将IP数据报(分组)从一个网路插口转发到另一个网路插口,带有多网路插口(网卡)的主机也能承当转发分组的功能,这种主机称为作为路由器使用的主机。
如果把一个村落比喻成一个小的局域网,那路由器就相当于联接村落的桥梁,路由器属于中间系统,所以联接不同网路的路由器须要实现不同的链路层合同,完成不同链路层的翻译转换功能;
另一方面,路由器实现链路层+网络层这2层就够了,而毋须实现传输层和应用层,这是由它的功能(实现分组交换)决定的。
每个IP分组都是一个IP数据报,包含发送方和接收方的第三层地址(IP地址),即32位的IPv4或128位的IPv6,IP数据报首部中的目的地址决定将该数据报发往何处,而作出决定和发送数据报到下一跳的过程叫转发,转发依赖于路由表,是储存于显存中的一个数据结构。
十、IP协议格式:
在贴出IP协议格式之前,我们可以构想一下,IP协议须要包括什么信息,这比直接上图+死记硬背要好。
根据之前封装的描述,显然,IP数据报应当是包括IP首部+数据负载,而这个不透明的负载(Payload)来自于TCP、UDP或则其他。
所以我们讲IP数据报格式,其实就是IP首部的组成和结构,因为数据负载来自于下层,而封装的本质要求下层的数据对上层隐藏、无须解释,既然IP的Payload对于IP层透明,那自然没哪些可讲的。
IP首部由各类不同用途和含意的数组组成。因为IP分32位的IPv4和128位的IPv6,所以IP首部须要包括版本号数组拿来分辨这两种情况。
因为IP负责分组转发,所以IP首部应当包括目的IP地址,用于路由转发逻辑的处理,另外接收端可能须要找到该分组的来源,所以也应当包含来源IP地址。
TCP、UDP、ICMP、IGMP都通过IP数据报传输,所以在IP首部,需要包含一个合同数组,用于分辨该IP数据报承载的是哪种类型的合同。
IP不纠错,但是须要检测错误,数据在传输过程中,有可能出错,导致接收到的数据跟发送的不一样,所以接收端须要有方式晓得传输过程中,数据是否跟发送端一致,所以颈部校验和数组也是必要的。
因为IP要处理分片和重组,所以IP首部须要包含相关信息,以支持该功能。
IP分IPv4和IPv6两种,协议格式不同,本文述说以IPv4为主,先给一个IPv4的数据报图,不带选项的IP数据报背部为20字节。
版本,IP协议的第一个数组都是版本数组,这也是IPv4和IPv6惟一相同的数组,IP数据报的版本数组为4对应IPv4,为6对应IPv6,主机或则路由器可以依照版本数组,分别处理IPv4或IPv6(称为双栈)。
IHL,Internet颈部厚度,该数组为4位,表示腰部(包括选项)32位字的数目,也就是说,真正的用字节表示的颈部厚度应当是IHL的值,再减去4(32位=4字节),因为4位能表示的最大2进制为1111,对应十进制15,所以IPv4的首部最多60(15*4)字节。
DS,服务类型数组占6bit,显示控制通知(ECN)占2bit,一共8bit,该8bit拿来替换了最初版本的服务类型(ToS)字段,原因是ToS似乎没怎样被用。
总宽度数组是IP数据报的总宽度,包括首部和数据。
接下来的32位字(4字节),标识(16bit)+标志(3bit)+分片偏斜(13bit)用于分片和重组逻辑。
TTL,生存期数组用于设置数据报可经过路由器数目的上限。超此上限的IP数据报将被遗弃。
协议数组,8bit,提供多路分解功能,满足IP协议可用于携带多种(TCP、UDP、ICMP、IGMP等)协议类型的有效荷载的要求,TCP对应值17,UDP对应值为6。
头部校准和数组仅估算IPv4腹部,不包括数据,数据(Payload)的校准由传输层合同去保证,校验和的涵义很简单明了,在发送端按照IP背部的诸位估算出一个数值,接收端按照接收到的IP背部的诸位重算一个数值,如果该值等于校验和数组,那就哦了,否则,传输过程中出错了,这个IP数据报不靠谱,扔了吧。
十一、分片和重组:
链路层对可传输的帧有一个最大宽度的限制,以太网对数据帧的宽度上限是1500字节,链路层可传输帧的宽度限制称作最大传输单元(MTU)。
如果IP层有一个数据报要传,且数据宽度比链路层的MTU还大,那么IP层就须要对该数据报分片(fragmentation),把超限的数据报切分为若干片,使得每片都大于MTU限制。
IP层接收到一份要发送的数据报时,通过选路逻辑来决定向那个插口(网卡)发送数据,发送数据之前,需要查询该插口获得其MTU,然后将数据报宽度与MTU进行比较,如果须要,则进行分片,分片可以发生在原始发送端主机,也可以发生在中间路由器上。
IP数据报分片后,到达目的地后才进行重新组装,恢复分片前的IP数据报结构,重组由目的主机的IP层完成,因此,分片和重组对传输层(TCP、UDP)透明,IP首部中的标示、标志、分片偏斜数组为分片和重组提供了足够的信息。
IP数据报首部中的标示(16bit)保存分片的惟一值,这意味着属于同一IP数据报的多个分片拥有相同的标示值;
标志(3bit)字段中的一位拿来表示“是否有更多的片”,除最后一片外,其他组成数据报的分片该位设1,最后一片置0表示没有更多的片,也就是最后一片;片偏斜数组拿来标示该片在原始IP数据报中的位置。
当IP数据报切分为多个分片(IP数据报)后,每个分片的总宽度数组(16bit)要修改为该片的宽度值。
对链路层而言,不管是完整的IP数据报,还是IP数据报的一个分片,都以IP分组同等视之,分组是IP层把数据报传递给链路层的一个概念,既可能是一个独立IP数据报也可能是一个IP数据报的分片。
每个分组(分片)都有自己的IP首部,并在选路时与其他分组(分片)独立路由,所以这种分片抵达目的端可能失序,但IP首部有足够信息重新组装这种片。
任何一个分片的遗失,都要造成重传整个数据报,这是因为重传机制在传输层,而分片对传输层透明。
上图是UDP数据报在IP层的分片示例,可见UDP首部只存在第一个分组(分片)之中,这很容易理解面试时让你说tcp协议,因为经传输层封装后的数据报对于IP层而言是透明的,IP不分辨UDP首部和UDP数据,它们都是不透明的Payload。
接收端在收到IP分片后,相同标示值的分片属于同一个被切分的数据报,然后对分片偏斜排序,更多片标志位为0的分组是最后一片,排序后的分组,如果分配偏斜连续,且最后一个分组也抵达,则表示整个数据报都抵达了,则恢复数据报,否则继续等待。
十二、IP转发:
IP转发的概念很简单,就是路由器为IP数据报选购一个插口发送出去,从发送端到目的端,之间经历的所有路由器构成网路的完整路径,这跟从家到公司经过的所有路口构成的路径类似。
当网路插口(网卡)收到数据报时,IP模块检测数据报目的地址是否为自己的IP地址,如果是,数据报交付给由合同数组指定的合同模块(TCP、UDP等),如果不是,则判定IP层是否配置为路由器,如果是,则转发,如果不是,丢弃,因为主机不转发这些不是由它生成的数据报。
IP层包含一些坐落显存中的信息,称为路由表,每次转发数据报时,都要查询路由表,执行最长前缀匹配法,决定选购那个路由表项做数据转发。IP转发逐跳进行,每次转发假定离目的地更近一步,路由器和主机不包含到目的地的完整路径信息。
路由表是路由条目的列表,每个路由条目包括以下几项关键信息。
目的地:一个32位数组,用于与网段操作结果相匹配。掩码:一个32位数组,用于与IP数据报中的目的IP地址做按位与操作。下一跳:下一个IP实体(路由器或则主机)的32位IP地址,数据报将被转发到该地址。接口:用于将数据报发送给下一跳的网路插口(网卡)。
选路过程,首先取出数据报中的目的IP地址,然后与路由条目的网段数组进行按位与,按位与的结果若果等于路由条目的目的地,则该条目与目的地IP匹配,该条目步入候选集合。
从候选集合中选择最匹配的条目,即网段最多位为1的条目,取出下一跳数组作为转发数据报的下一跳IP地址。
通过最匹配条目的网路插口,发送到下一跳。
如果没有匹配条目,则数据报未能交付,通过ICMP发送“主机不可达”通知发送主机。
通常路由表会有一个默认路由项目,用于默认路由,每经过一个路由器,IP首部中的TTL数组都要自减1。
学习C/C++的伙伴可以私信回复小编“学习”领取全套免费C/C++学习资料、视频