Linux从青铜到王者第二十篇:Linux网络基础第三篇之IP协议
Posted 森明帮大于黑虎帮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux从青铜到王者第二十篇:Linux网络基础第三篇之IP协议相关的知识,希望对你有一定的参考价值。
系列文章目录
文章目录
前言
一、IP协议基本概念
主机: 配有IP地址, 但是不进行路由控制的设备; 路由器: 即配有IP地址, 又能进行路由控制; 节点: 主机和路由器的统称。
二、IPv4首部
4位首部长度 和TCP报头中的4位首部长度一样,代表的是IP报头的长度是多少个4字节,4位比特位能够表示的最大数字是15,即IP头部的最大长度是15*4 = 60字节16位总长度 指的是IP数据报整体占多少个字节。用总长度-报头即为有效载荷。
- 4位版本号(version):
- 指定IP协议的版本, 对于IPv4来说, 就是4。
- 4位头部长度(header length):
- IP头部的长度是多少个32bit, 也就是 length * 4 的字节数. 4bit表示最大的数字是15, 因此IP头部最大长度是60字节。
- 8位服务类型(Type Of Service):
- 3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(必须置为0). 4位TOS分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本. 这四者相互冲突, 只能选择一个. 对于ssh/telnet这样的应用程序, 最小延时比较重要; 对于ftp这样的程序, 最大吞吐量比较重要。
- 16位总长度(total length):
- IP数据报整体占多少个字节。
- 16位标识(id):
- 唯一的标识主机发送的报文. 如果IP报文在数据链路层被分片了, 那么每一个片里面的这个id都是相同的。
- 3位标志字段:
- 第一位保留(保留的意思是现在不用, 但是还没想好说不定以后要用到). 第二位置为1表示禁止分片, 这时候如果报文长度超过MTU, IP模块就会丢弃报文. 第三位表示"更多分片", 如果分片了的话,最后一个分片置为1, 其他是0. 类似于一个结束标记。
-
第一位表示保留位。
第二位表示禁止分片。
第三位表示分片是否结束。
1:表示后面还有分片
0:表示后面没有分片 - 13位分片偏移(framegament offset):
- 是分片相对于原始IP报文开始处的偏移. 其实就是在表示当前分片
在原报文中处在哪个位置. 实际偏移的字节数是这个值 * 8 得到的. 因此, 除了最后一个报文之外, 其他报文的长度必须是8的整数倍(否则报文就不连续了)。 - 8位生存时间(Time To Live, TTL):
- 数据报到达目的地的最大报文跳数. 一般是64. 每次经过一个路由, TTL-= 1, 一直减到0还没到达, 那么就丢弃了. 这个字段主要是用来防止出现路由循环。
- 8位协议:
- 表示上层协议的类型。
- 16位头部校验和:
- 使用CRC进行校验, 来鉴别头部是否损坏。
- 32位源地址和32位目标地址:
- 表示发送端和接收端
- 选项字段(不定长, 最多40字节):
ip协议用来表示一条数据所使用的是:(一条ip数据报)
16位总长度 + 16位标识 + 3位标志 + 13位片偏移。
16位总长度能够标识的数据最大为65536Byte,如果传输层递交给网络层ip协议的数据超过65536Byte,那应该如何做?
答案:是在网络层的ip协议进行分片传输。
那么,问题来了,TCP需要ip协议进行分片吗?
解答:不需要进行分片,因为TCP协议在传输数据的时候,严格按照MSS进行传输,而MSS一定是小于MTU的,而一般网卡的MTU都是1500字节,换句话说,TCP在每次传输数据的时候都是不会超过1500字节的。因此,MSS是远远小于65536字节的,因此也就不会触发ip协议进行分片传输。
UDP需要ip协议进行分片吗?
解答:有可能需要进行分片,因为UDP协议是没有类似于MSS存在的,因此,UDP的数据的最大长度是65536字节,网络层递交给数据链路层大小必须小于MTU的,因此,一旦UDP递交给网络层ip协议的数据加上ip协议报头之后,总长度大于了当前主机的MTU大小时,就会需要进行分片传输。
注:因为UDP协议是不可靠的,在ip数据报转发的时候,都有自己的路由转发路径,可能会造成丢失。
分片丢了会重发分片还是所有数据一起重发?
三、网络号和主机号
ip地址的分为两个部分,网络号和主机号。
网络号:保证互相连接的两个网段具有不同的标识。
主机号:同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号。
- 不同的子网其实就是把网络号相同的主机放到一起。
- 如果在子网中新增一台主机, 则这台主机的网络号和这个子网的网络号一致, 但是主机号必须不能和子网中的其他主机重复。
ipv4版本的ip地址:本质是uint32_t,范围是[0 , 232 - 1]。
通过合理设置主机号和网络号, 就可以保证在相互连接的网络中, 每台主机的IP地址都不相同。
四、早期地址管理方式
那么问题来了, 手动管理子网内的IP, 是一个相当麻烦的事情:
- 有一种技术叫做DHCP, 能够自动的给子网内新增主机节点分配IP地址, 避免了手动管理IP的不便。
- 一般的路由器都带有DHCP功能. 因此路由器也可以看做一个DHCP服务器。
过去曾经提出一种划分网络号和主机号的方案, 把所有IP 地址分为五类, 如下图所示(该图出 自[TCPIP]。
早期ip地址的划分方式:A类、B类、C类、D类、E类。
A类:
B类:
C类:
五、CIDR(Classless Interdomain Routing)方式
随着Internet的飞速发展,这种划分方案的局限性很快显现出来,大多数组织都申请B类网络地址, 导致B类地址很快就分配完了, 而A类却浪费了大量地址。
- 例如, 申请了一个B类地址, 理论上一个子网内能允许6万5千多个主机. A类地址的子网内的主机数更多。
- 然而实际网络架设中, 不会存在一个子网内有这么多的情况. 因此大量的IP地址都被浪费掉了。
针对这种情况提出了新的划分方案, 称为CIDR(Classless Interdomain Routing)。
- 引入一个额外的子网掩码(subnet mask)来区分网络号和主机号。
- 子网掩码也是一个32位的正整数. 通常用一串 “0” 来结尾。
- 将IP地址和子网掩码进行 “按位与” 操作, 得到的结果就是网络号。
- 网络号和主机号的划分与这个IP地址是A类、B类还是C类无关。
计算当前网络的网络号:
网络号 = ip 地址 & 子网掩码
注意:这已经和之前的ABC类地址没有关系了,这是新的划分方式。
如何得到当前子网中的IP地址使用多少个比特位作为主机号?
解答:子网掩码按位取反等于当前最大的主机号:
取反之后,有多少比特位为1,则表示当前子网当中的ip地址使用了多少个比特位当作是主机号。
- 例题:
- ip:172.16.99.129,子网掩码:255.255.255.0
- 如果想要将该子网平均划分为4个子网,则对应的子网掩码是什么?
六、特殊的IP地址
- 在一个网段中都会有一个网络号的和广播号,即 192.0.0.0 ~ 192.0.0.255
- 网络号:主机号全为0的ip地址,就为该网段中的网络号
- 广播号:主机号中全为1的ip地址,就为该网段中的广播号
- 127.0.0.1 :本地回环网卡地址(通常用来测试自己机器的网络连通性)
- 0.0.0.0:代表本地所有的网卡地址
七、IP地址的数量限制
- 我们知道, IP地址(IPv4)是一个4字节32位的正整数. 那么一共只有 2的32次方 个IP地址, 大概是43亿左右. 而TCP/IP协议规定, 每个主机都需要有一个IP地址,这意味着, 一共只有43亿台主机能接入网络么?
- 实际上, 由于一些特殊的IP地址的存在, 数量远不足43亿; 另外IP地址并非是按照主机台数来配置的, 而是每一个网卡都需要配置一个或多个IP地址。
- CIDR在一定程度上缓解了IP地址不够用的问题(提高了利用率, 减少了浪费, 但是IP地址的绝对上限并没有增加), 仍然不是很够用. 这时候有三种方式来解决:
- 动态分配IP地址: 只给接入网络的设备分配IP地址. 因此同一个MAC地址的设备, 每次接入互联网中, 得到的IP地址不一定是相同的。
- NAT技术(后面会重点介绍)。
- IPv6: IPv6并不是IPv4的简单升级版. 这是互不相干的两个协议, 彼此并不兼容; IPv6用16字节128位来表示一个IP地址; 但是目前IPv6还没有普及。
八、路由控制
IP协议相当于OSI参考模型中的第3层——网络层。
IP网络层的主要作用是“实现终端节点之间的通信”。这种终端节点之间的通信也叫“点对点(end-to-end)通信”。
IP网络层的下一层——数据链路层的主要作用是在互连同一种数据链路的节点之间进行包传递。而一旦跨越多种数据链路,就需要借助网络层。网络层可以跨越不同的数据链路,即使是在不同的数据链路上也能实现两端节点之间的数据包传输。
- 首先我们要知道路由器分为WAN和LAN口:
- WAN:连接上级路由器
- LAN:用来组装当前路由器的子网
路由器LAN口连接的主机, 都从属于当前这个路由器的子网中。
① 从运营商机房拉出的网线插在了家用路由器的WAN口上。
② 个人设备是插在家用路由器的LAN口上。
其次,我们需要知道网络数据的五元组信息。
源ip、目的ip、源端口、目的端口、协议。
在路由设备中都会有一个路由表,路由表记录了当前的路由项,用route命令查看:
那么路由器是如何进行网络转发的呢?
首先用网络数据中的目的ip和路由项当中的子网掩码进行按位与操作(需要注意的是,该目的ip先和非网关的路由项进行操作,最后再和网关路由项进行操作)。
其次将按位与操作的结果和路由项的Destination进行对比
① 如果说没有对比上,则代表该条数据不是往该子网当中进行转发。
② 如果说对比上了,则代表该条数据是往该子网当中的某一个主机进行转发的。
需要注意的是:
① 如果该条数据的目的ip是当前子网的某一主机,则不需要WAN的转发,直接走路由器的LAN口
② 如果该条数据的目的ip是互联网当中的某一个主机,则需要经过WAN口的转发,传输到上级路由器再进行路由。
③ 路由表也是需要更新的。
路由的过程, 就是这样一跳一跳(Hop by Hop) “问路” 的过程。所谓 “一跳” 就是数据链路层中的一个区间. 具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间。
IP数据包的传输过程也和问路一样。
当IP数据包, 到达路由器时, 路由器会先查看目的IP。
路由器决定这个数据包是能直接发送给目标主机, 还是需要发送给下一个路由器。
依次反复, 一直到达目标IP地址
总结
以上就是今天要讲的内容,本文详细介绍了网络层IP协议保证传输效率和可靠传输的方法,网络提供了大量的方法供我们使用,非常的便捷,我们务必掌握。希望大家多多支持!另外如果上述有任何问题,请懂哥指教,不过没关系,主要是自己能坚持,更希望有一起学习的同学可以帮我指正,但是如果可以请温柔一点跟我讲,爱与和平是永远的主题,爱各位了。加油啊!
以上是关于Linux从青铜到王者第二十篇:Linux网络基础第三篇之IP协议的主要内容,如果未能解决你的问题,请参考以下文章
Linux从青铜到王者第二十四篇:Linux网络基础第四篇之WebSocket协议
C++从青铜到王者第二十篇:STL之setmapmultisetmultimap的初识
Linux从青铜到王者第二十三篇:Linux网络基础第四篇之kcp协议