linux从青铜到王者第二十篇:linux网络基础第三篇之ip协议

森明帮大于黑虎帮 森明帮大于黑虎帮     2022-12-20     406

关键词:

系列文章目录



前言


一、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网络基础第三篇之数据链路层

系列文章目录文章目录系列文章目录前言一、数据链路层的以太网协议二、认识MAC地址三、对比理解MAC地址和IP地址四、ARP协议的作用五、ARP数据报格式五、ARP协议工作流程六、ARP缓存表七、DNS(DomainNameSystem)八、NAT协议九、NAPT协... 查看详情

c++从青铜到王者第二十篇:stl之setmapmultisetmultimap的初识(代码片段)

系列文章目录文章目录系列文章目录前言一、关联式容器二、键值对三、树形结构的关联式容器四、set的介绍和使用1.set的介绍2.set的使用1.set的模板参数列表2.set的构造3.set的容量4.set的修改操作5.set的迭代器五、map的介绍和使用1... 查看详情

linux从青铜到王者第二十二篇:linux高级io(代码片段)

系列文章目录文章目录系列文章目录前言一、五种IO模型1.阻塞IO2.非阻塞IO3.信号驱动IO4.异步IO5.IO多路转接二、高级IO重要概念1.同步通信vs异步通信2.阻塞vs非阻塞三、I/O多路转接之select1.select函数的作用2.select函数的原型3.fd_set结... 查看详情

linux从青铜到王者第十八篇:linux网络基础第二篇之tcp协议

系列文章目录文章目录系列文章目录前言一、TCP面向字节流二、TCP粘包问题1.什么是TCP粘包问题2.TCP粘包问题的解决办法三、TCP异常情况四、TCP协议1.TCP协议段格式2.确认应答(ACK)机制3.超时重传机制4.连接管理机制1、TCP三次握手1.... 查看详情

linux从青铜到王者第十七篇:linux网络基础第二篇之udp协议

系列文章目录文章目录系列文章目录前言一、传输层1.再谈端口号2.端口号范围划分3.认识知名端口号(Well-KnowPortNumber)4.进程和端口号两个问题5.netstat查看网络状态二、UDP协议1.UDP协议端格式2.UDP的特点3.面向数据报4.UDP的缓冲区5.UDP... 查看详情

linux从青铜到王者第十六篇:linux网络基础第二篇之http协议(代码片段)

系列文章目录文章目录系列文章目录前言一、HTTP协议的概念二、HTTP协议URL的解释三、HTTP协议的数据流四、HTTP协议格式1.HTTP请求2.HTTP响应五、HTTP协议格式图解六、HTTP协议版本七、HTTP协议请求方法1.GET:获取资源2.POST:... 查看详情

linux从青铜到王者第十九篇:linux网络基础第二篇之滑动窗口流量控制拥塞控制延迟应答捎带应答

系列文章目录文章目录系列文章目录前言👮一、滑动窗口💰一、滑动窗口的由来💰二、滑动窗口存在的问题💷1.滑动窗口的大小💷2.数据包已经传输给对方,但是对方返回的ACK数据包丢失💷3.传输的... 查看详情

linux从青铜到王者第十二篇:linux进程间信号第二篇(代码片段)

系列文章目录文章目录系列文章目录前言一、阻塞信号1.信号其他相关常见概念2.在内核中的表示3.sigset_t信号集4.信号集操作函数5.sigprocmask函数6.sigpending函数二、捕捉信号1.内核实现信号的捕捉2.volatile关键字总结前言一、阻塞信... 查看详情

c++从青铜到王者第二十六篇:哈希(代码片段)

系列文章目录文章目录系列文章目录前言一、unordered系列关联式容器二、unordered_map1.unordered_map的文档介绍2unordered_map的接口介绍三、unordered_set四、底层结构1.哈希概念2.哈希冲突3.哈希函数4.哈希冲突的解决之闭散列-线性探测和... 查看详情

c++从青铜到王者第二十二篇:c++11(代码片段)

系列文章目录文章目录系列文章目录前言一、C++11简介(了解)二、列表初始化(了解)1.C++98中的初始化问题2.内置类型的列表初始化3.自定义类型的列表初始化三、变量类型推导(了解)1.为什么需要类型推导2.decltype类型推... 查看详情

linux从青铜到王者第十四篇:linux网络基础第一篇

系列文章目录文章目录系列文章目录前言一、计算机网络的发展过程1.独立模式2.网络互联模式3.局域网LAN4.广域网WAN二、认识计算机网络协议1.协议的概念2.什么是网络协议3.网络协议簇4.体系结构5.OSI七层模型6.TCP/IP五层(或四层)... 查看详情

c++从青铜到王者第二十三篇:c++异常(代码片段)

系列文章目录文章目录系列文章目录前言一、C语言传统的处理错误的方式二、C++异常概念三、异常的使用1.异常的抛出和捕获2.异常的重新抛出3.异常安全4.异常规范四、自定义异常体系五、C++标准库的异常体系六、... 查看详情

c++从青铜到王者第二十五篇:c++智能指针(代码片段)

系列文章目录文章目录系列文章目录前言一、常见面试题1.malloc/free和new/delete的区别2.内存泄漏1.内存泄漏概念与危害2.内存泄漏分类(了解)3.如何检测内存泄漏(了解)4.如何避免内存泄漏5.如何一次在堆上申请4G... 查看详情

c++从青铜到王者第二十四篇:c++的类型转换(代码片段)

系列文章目录文章目录系列文章目录前言一、C语言中的类型转换二、为什么C++需要四种类型转换三、C++强制类型转换1.static_cast类型转换2.reinterpret_cast类型转换3.const_cast类型转换4.dynamic_cast类型转换5.explicit总结前言一... 查看详情

c++从青铜到王者第二十七篇:特殊类设计(代码片段)

系列文章目录文章目录系列文章目录前言一、请设计一个类,只能在堆上创建对象二、请设计一个类,只能在栈上创建对象三、请设计一个类,不能被拷贝四、请设计一个类,不能被继承五、请设计一个类,... 查看详情

linux从青铜到王者第十五篇:linux网络编程套接字两万字详解(代码片段)

系列文章目录文章目录系列文章目录前言一、网络数据的五元组信息1.理解源IP地址和目的IP地址2.理解"端口号"和"进程ID"3.理解源端口号和目的端口号4.理解TCP协议5.理解UDP协议二、主机字节序<===>网络字... 查看详情

c++从青铜到王者第二十一篇:哈希的应用之位图布隆过滤器(代码片段)

系列文章目录文章目录系列文章目录前言一、位图1.位图的概念2.位图的面试题3.位图的实现4.位图的应用二、布隆过滤器1.布隆过滤器的提出2.布隆过滤器的概念3.布隆过滤器的插入3.布隆过滤器的查找4.布隆过滤器的删除5.布隆过... 查看详情

c++从青铜到王者第十篇:stl之vector类的模拟实现(代码片段)

系列文章目录文章目录系列文章目录前言一、vector深度剖析及模拟实现1.vector的核心接口模拟实现2.vector的核心接口测试3.使用memcpy拷贝问题4.动态二维数组理解总结前言一、vector深度剖析及模拟实现1.vector的核心接口模拟实现names... 查看详情