当前位置: 首页 > 编程日记 > 正文

浅谈网络协议(四) IP的由来--DHCP与PXE

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

上一节说过,IP就是一台计算机的通讯地址,要和其他机器通讯,就需要一个通讯地址,就要给网卡配置这么一个地址。

配置 IP

那如何配置呢?可以使用 ifconfig,也可以使用 ip addr。设置好了之后,用这两个命令,将网卡 up 一下,就可以开始工作了。

使用 net-tools:$ sudo ifconfig eth1 10.0.0.1/24
$ sudo ifconfig eth1 up
使用 iproute2:$ sudo ip addr add 10.0.0.1/24 dev eth1
$ sudo ip link set up eth1

这个配置是不是很简单?但是如果胡乱配置会怎么样?例如,旁边的机器都是 192.168.1.x,我非得配置一个 16.158.23.6,会出现什么现象呢?

不会出现任何现象,就是包发不出去。为什么发不出去呢?

之前讲过,只要是在网络上的数据包,都是完整的,可以有下层没上层,绝对不可能有上层没下层。

所以仅有源 IP 地址 16.158.23.6,也有目标 IP 地址 192.168.1.6,可是没有目标的 MAC 地址,所以包还是发不出去。
那怎么获取目标的 MAC 地址呢?Linux 首先会判断,要去的地址和本机是不是同一个网段,或者和网卡是不是同一网段。只有是一个网段的,它才会发送 ARP 请求,获取 MAC 地址。如果发现不是呢?

Linux 默认的逻辑是,如果这是一个跨网段的调用,它便不会直接将包发送到网络上,而是企图将包发送到网关。

如果配置了网关的话,Linux 会获取网关的 MAC 地址,然后将包发出去。对于 192.168.1.6 这台机器来讲,虽然路过它家门的这个包,目标 IP 是它,但是 MAC 地址不是它的,所以它的网卡是不会把包收进去的。如果没有配置网关,那包就发不出去了。

如果将网关配置为 192.168.1.6 呢?不可能,Linux 不会让你配置成功的,因为网关要和当前的网络至少一个网卡是同一个网段。

所以,当需要手动配置一台机器的网络 IP 时,一定要向网络管理员给你分配一段正确的 IP 地址。当然,真正配置的时候,一定不是直接用命令配置的,而是放在一个配置文件里面。不同系统的配置文件格式不同,但是无非就是 CIDR、子网掩码、广播地址和网关地址。

动态主机配置协议(DHCP)

配置了 IP 之后一般不能变的,所以手动配置 IP 会有很大的限制,毕竟经常的客户端变动等等。因此,需要有一个自动配置的协议来自动化的分配 IP ,也就是动态主机配置协议(Dynamic Host Configuration Protocol)。

配置一段共享的 IP 地址后,每一台机器新接入时都会通过 DHCP 协议来这个共享的 IP 地址里申请,然后自动配置好就可以了。机器离线之后,就会把 IP 换回去,别的机器可以再次使用。

解析 DHCP 的工作方式

当一台机器新加入一个网络的时候,只知道自己的 MAC 地址,还没有分配 IP,这个时候就靠吼了。这一步,我们称为DHCP Discover。

新来的机器使用 IP 地址 0.0.0.0 发送了一个广播包,目的 IP 地址为 255.255.255.255。广播包封装在 UDP 里面,UDP 封装在 BOOTP 里面。其实 DHCP 是 BOOTP 的增强版,但是如果你去抓包的话,很可能看到的名称还是 BOOTP 协议。

广播的格式就像这样:

1

如果一个网络管理员在网络里面配置了DHCP Server的话,他就相当于这些 IP 的管理员。他立刻能知道来了一个“新人”。这个时候,我们可以体会 MAC 地址唯一的重要性了。当一台机器带着自己的 MAC 地址加入一个网络的时候,MAC 是它唯一的身份,如果连这个都重复了,就没办法配置了。

只有 MAC 唯一,IP 管理员才能知道这是一个新人,就会给他分配一个 IP 地址,这个过程我们称为DHCP Offer。同时,DHCP Server 为此客户保留为它提供的 IP 地址,从而不会为其他 DHCP 客户分配此 IP 地址。

DHCP Offer 的格式就像这样:

2

DHCP Server 仍然使用广播地址作为目的地址,因为,此时请求分配 IP 的新人还没有自己的 IP。除此之外,服务器还发送了子网掩码、网关和 IP 地址有效期等信息。

如果有多个 DHCP Server,这台新机器会收到多个 IP 地址,它会选择其中一个 DHCP Offer,一般是最先到达的那个,并且会向网络发送一个 DHCP Request 广播数据包,包中包含客户端的 MAC 地址、接受的分配中的 IP 地址、提供此 IP 的 DHCP 服务器地址等,并告诉所有 DHCP Server 它将接受哪一台服务器提供的 IP 地址,告诉其他 DHCP 服务器,并请求撤销它们提供的 IP 地址,以便提供给下一个 IP 分配请求者。

DHCP Request:
3

此时,由于还没有得到 DHCP Server 的最后确认,客户端仍然使用 0.0.0.0 为源 IP 地址、255.255.255.255 为目标地址进行广播。在 BOOTP 里面,接受某个 DHCP Server 的分配的 IP。

当 DHCP Server 接收到客户机的 DHCP request 之后,会广播返回给客户机一个 DHCP ACK 消息包,表明已经接受客户机的选择,并将这一 IP 地址的合法分配信息和其他的配置信息都放入该广播包,发给客户机,欢迎它加入网络大家庭。

DHCP ACK:
4

最终分配达成的时候,还是需要广播一下,让大家都知道。

IP 地址的收回和续期

如果不用的话,收回就收回了。就像你租房子一样,如果还要续租的话,不能到了时间再续租,而是要提前一段时间给房东说。DHCP 也是这样。

客户机会在有效期过去 50% 的时候,直接向为其提供 IP 地址的 DHCP Server 发送 DHCP request 消息包。客户机接收到该服务器回应的 DHCP ACK 消息包,会根据包中所提供的新的有效期以及其他已经更新的 TCP/IP 参数,更新自己的配置。这样,IP 配置更新就完成了。

DHCP 协议大部分人都知道,但是其实里面隐藏着一个细节,很多人可能不会去注意。接下来,还有一个有意思的事情:网络管理员不仅能自动分配 IP 地址,还能帮你自动安装操作系统!

预启动执行环境(PXE)

一台没有操作系统的空机器,很多人还是会安装系统的。但是如果给你几百台的空的机器呢?数据中心的管理员就有可能遇到这种问题。那么能不能自动安装系统呢?

仔细一想,还是挺有难度的。
正常安装操作系统,应该有个光盘,再不济得有个U盘。数据中心又不能用这些,想了一个办法就是要安装的操作系统放在一个服务器上,让客户端去下载。那么如何去实现呢?一开始空机器上面也没有客户端,更不知道去哪里下载。

这个过程和操作系统启动的过程有点儿像。首先,启动 BIOS。这是一个特别小的小系统,只能干特别小的一件事情。其实就是读取硬盘的 MBR 启动扇区,将 GRUB 启动起来;然后将权力交给 GRUB,GRUB 加载内核、加载作为根文件系统的 initramfs 文件;然后将权力交给内核;最后内核启动,初始化整个操作系统。

安装操作系统的过程,只能插在 BIOS 启动之后了。因为没安装系统之前,连启动扇区都没有。因而这个过程叫做预启动执行环境(Pre-boot Execution Environment),简称PXE。

PXE 协议分为客户端和服务器端,由于还没有操作系统,只能先把客户端放在 BIOS 里面。当计算机启动时,BIOS 把 PXE 客户端调入内存里面,就可以连接到服务端做一些操作了。

再 PXE 的客户端启动起来之后,发送一个 DHCP 的请求,让 DHCP Server 给它分配一个地址。PXE 客户端有了自己的地址,那它怎么知道 PXE 服务器在哪里呢?对于其他的协议,都好办,要么人告诉他。例如,告诉浏览器要访问的 IP 地址,或者在配置中告诉它;例如,微服务之间的相互调用。

但是 PXE 客户端启动的时候并没有那些。所以 DHCP Server 除了分配 IP 地址以外,还可以做一些其他的事情。这里有一个 DHCP Server 的一个样例配置:

ddns-update-style interim;
ignore client-updates;
allow booting;
allow bootp;
subnet 192.168.1.0 netmask 255.255.255.0
{
option routers 192.168.1.1;
option subnet-mask 255.255.255.0;
option time-offset -18000;
default-lease-time 21600;
max-lease-time 43200;
range dynamic-bootp 192.168.1.240 192.168.1.250;
filename "pxelinux.0";
next-server 192.168.1.180;
}

默认的 DHCP Server 是需要配置的,无非是我们配置 IP 的时候所需要的 IP 地址段、子网掩码、网关地址、有效期等。如果想使用 PXE,则需要配置 next-server,指向 PXE 服务器的地址,另外要配置初始启动文件 filename。

这样 PXE 客户端启动之后,发送 DHCP 请求之后,除了能得到一个 IP 地址,还可以知道 PXE 服务器在哪里,也可以知道如何从 PXE 服务器上下载某个文件,去初始化操作系统。

解析 PXE 的工作过程

接下来我们来详细看一下 PXE 的工作过程。

首先,启动 PXE 客户端。第一步是通过 DHCP 协议分配一个 IP 地址,同时也给它 PXE 服务器的地址、启动文件名称 pxelinux.0。

其次,当 PXE 客户端知道要去 PXE 服务器地址与下载文件名之后,就会使用 TFTP 协议开始下载。所以 PXE 服务器上,往往还需要有一个 TFTP 服务器。PXE 客户端向 TFTP 服务器请求下载这个文件。

然后,PXE 客户端在下载完成后直接开始执行这个文件。这个文件会指示 PXE 客户端,向 TFTP 服务器请求计算机的配置信息 pxelinux.cfg。TFTP 服务器会给 PXE 客户端一个配置文件,里面会说内核、initramfs 的位置。PXE 客户端会请求这些文件。

最好,启动 Linux 内核。一旦启动了操作系统,以后就啥都好办了。

5

转载于:https://my.oschina.net/OSrainn/blog/1924654

相关文章:

(C++)1026 程序运行时间

#include<cstdio> const int CLK_TCK100;int main(){ //1.读入c1,c2int c1,c2;scanf("%d%d",&c1,&c2); //2.定义常量CLK_TCK100 //难点&#xff1a;不足 1 秒的时间四舍五入到秒 --不用round()&#xff0c;避免浮点数运算 int dif c2-c1;if(dif%100&…

Spring中@Autowired注解、@Resource注解的区别

Spring不但支持自己定义的Autowired注解&#xff0c;还支持几个由JSR-250规范定义的注解&#xff0c;它们分别是Resource、PostConstruct以及PreDestroy。  Resource的作用相当于Autowired&#xff0c;只不过Autowired按byType自动注入&#xff0c;而Resource默认按 byName自…

(C++)1046 划拳

划拳是古老中国酒文化的一个有趣的组成部分。酒桌上两人划拳的方法为&#xff1a;每人口中喊出一个数字&#xff0c;同时用手比划出一个数字。如果谁比划出的数字正好等于两人喊出的数字之和&#xff0c;谁就赢了&#xff0c;输家罚一杯酒。两人同赢或两人同输则继续下一轮&…

JAVA中重写equals()方法的同时要重写hashcode()方法

object对象中的 public boolean equals(Object obj)&#xff0c;对于任何非空引用值 x 和 y&#xff0c;当且仅当 x 和 y 引用同一个对象时&#xff0c;此方法才返回 true&#xff1b;注意&#xff1a;当此方法被重写时&#xff0c;通常有必要重写 hashCode 方法&#xff0c;以…

从0到1,苏宁API网关的演进之路

http://www.infoq.com/cn/articles/suning-11-11-api-gateway?utm_campaigninfoq_content&utm_sourceinfoq&utm_mediumfeed&utm_termglobal 2012年&#xff0c;在开放云融推动各产业全面发展的大背景下&#xff0c;苏宁API对外开放。基于苏宁各内部业务系统的资源…

HTML 注意事项

这行与下面图片的间距比较小asdf 代码如下: <table id"table1"cellspacing"0"cellpadding"0"width"100%"border"0"><tbody><tr><td>这行与下面图片的间距比较小</td></tr><tr>&l…

(C++)1008 数组元素循环右移问题

#include<cstdio> //注意&#xff1a;不允许使用另外数组,序列结尾不能有多余空格,不能直接认为right<n //1.读入数组长度&#xff0c;和右移位数&#xff0c;读入数组 //2.未必要对实际数组进行循环右移&#xff0c;只要输出结果表现出那样就可以 int main(){int n…

C# 文件操作(上传 下载 删除 文件列表...)

using System.IO; 1.文件上传 ---------- 如下要点&#xff1a; HTML部分&#xff1a; <form id"form1" runat"server" method"post" enctype"multipart/form-data"> <input id"FileUpLoad" type"file" …

5个常用Java代码混淆器 助你保护你的代码

【IT168 技术文档】 从事Java编程的人都知道&#xff0c;可以通过逆向工程反编译得到Java程序的源代码&#xff0c;这种反编译工具之一就是JAD。因此&#xff0c;为保护我们的劳动成果&#xff0c;尽可能给反编译人员制造障碍&#xff0c;我们可以使用Java Obfuscator(Java混淆…

9.8.6恢复系统数据库

系统数据库和用户数据库一样容易发生故障&#xff0c;所以确保它们得到足够的保护十分重 要。一般来说&#xff0c;恢复系统数据库时有两种选择。可以从备份还原&#xff0c;或者从头重建它们。我 强烈推荐备份还原方法&#xff0c;因为从头重建意味着有人量的工作要做。由于系…

(C++)1012 数字分类

#include<cstdio> //用switch...case语句来对读入的数字进行分类 //1.读入N //2.A2需要设置变号器 //3.A3,A4需要设置计数器 //注意&#xff1a;某一类数可能根本不存在 int main(){int n;scanf("%d",&n);int res[5]{};//初始化为0 int count[5]{};whil…

老调重弹:插件式框架开发的一个简单应用

VS 2008最近要做一个应用程序检测程序&#xff0c;就是要检测服务器上各应用程序的运行情况&#xff0c;由于各应用程序的差异&#xff0c;很难做一个统一的探测程序&#xff0c;于是决定对任意一个应用程序都采用独立的一条探测规则。为了开发、部署的方便&#xff0c;考虑使用…

mathjax测试

O(∩_∩)O哈哈~&#xff0c;新开通博客测试。 mathjax公式测试。以下是latex公式 $a^2b^2c^2$ <!--more--> 多输入一点东东。新浪娱乐讯 1月3日&#xff0c;网络红人奶茶妹妹章泽天清空微博&#xff0c;而其男友刘强东也删除了“小天是我见过最单纯善良的人…只求以后可以…

Docker镜像使用

当运行容器时&#xff0c;使用的镜像如果在本地中不存在&#xff0c;docker 就会自动从 docker 镜像仓库中下载&#xff0c;默认是从 Docker Hub 公共镜像源下载。 下面我们来学习&#xff1a; 1、管理和使用本地 Docker 主机镜像2、创建镜像列出镜像列表 我们可以使用 docker …

(C++)1018 锤子剪刀布

#include<cstdio>int Map(char c){//将字母映射到数字 if(cB){return 0;}else if(cC){return 1;}else{return 2;} } //对决函数&#xff0c;返回1表示甲胜&#xff0c;0表示平局&#xff0c;-1表示乙胜 int ko(int i1,int i2){if((i11)%3i2){//甲胜 return 1;}else if(i…

我的软考之路(九)——总结篇

经过两个月的备战&#xff0c;软考总算结束了。软考虽然结束了&#xff0c;但是还需要简单的总结一下得与失。我从时间安排&#xff0c;到讲课做真题简单的回顾一下软考的整个过程。 时间安排&#xff1a; 对于时间的安排&#xff0c;整个小组成员每个人都有自己的看法&#xf…

problem-solving-with-algorithms-and-data-structure-usingpython(使用python解决算法和数据结构) -- 基本数据结构(二)...

中缀、前缀和后缀表达式 1. 前缀表达式符号要求所有运算符在它们处理的两个操作数之前。 2. 后缀表达式要求其操作符在相应的操作数之后。 考虑表达式 A B * C &#xff0c; A B C * 是等价的后缀表达式。操作数 A&#xff0c;B 和 C 保持在它们的相对位置&#xff0c;只有操…

赢在中国(08-02-27)

在Google Calendar中设置了赢在中国的日程&#xff0c;结果没有发短信给我&#xff08;是不是可以起诉它呢&#xff1f;和Google打打官司&#xff0c;可是成名的好机会啊&#xff1a;&#xff09;&#xff09;后面一节还是看到了&#xff0c;印象比较深的是最后一位做教育的选手…

(C++)1041 考试座位号

//B1041 #include<cstdio> //直接将试机号作为下标 struct student{long long no;int sit; };int main(){int n1,n2;//总共参与考试的人数&#xff0c;来迟的人数 student stus[1010];scanf("%d",&n1);long long no;int sit,test;for(int i0;i<n1;i){s…

Premiere制作VCD视频几个关键设置

一&#xff0c;视频设置 1&#xff0c;编码设置&#xff1a;不要选cinepak codec by radius,这个编码速度非常慢,图象也不清晰,一般只在电脑多多媒体交互式演示文件中使用。很多朋友遇到的“速度慢”、“不清晰”&#xff0c;多半是这里设置不合适造成。 2&#xff0c;帧尺寸&a…

qt中定时器Timer的使用

转载于:https://www.cnblogs.com/zhouwenJS/p/3762341.html

python基础===拆分字符串,和拼接字符串

给定某字符&#xff0c;只需要保留其中的有效汉字或者字母&#xff0c;数字之类的。去掉特殊符号或者以某种格式进行拆分的时候&#xff0c;就可以采用re.split的方法。例如 RESTART: Shell >>> s Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.19…

(C++)1036 跟奥巴马一起编程

#include<cstdio> //10列 共5行 131 //11列 共6行 141 //n%20 1n/2-21 //n%2!0 1(n-1)/2-11 int main(){int col,mid;char c;scanf("%d %c",&col,&c);//第一行for(int i 0;i<col;i){printf("%c",c);} printf("\n");//中间行/…

使用LINQ进行多表操作(二)

1:M或者M:M关系的多表操作表结构如下直接写表达式 //正常选取var user context.Users.Where(p >p.UserID 10300).Select(p >new{p, p.UserTags})//带条件选取var user context.Users.Where(p >p.UserID 10300).Select(p >new{p, UserTags p.UserTags.Where(o >…

分布式文件系统

PDF格式PPT下载&#xff1a;分布式文件系统 转载于:https://www.cnblogs.com/mfrbuaa/p/3765902.html

Codis 3.2 集群搭建与测试

这里首选分为四个步骤进行一、软件下载codis 3.2.2 https://github.com/CodisLabs/codis/releasescodis-src https://codeload.github.com/CodisLabs/codis/zip/release3.2zeepkeeper 3.5.4 http://ftp.twaren.net/Unix/Web/apache/zookeeper/zookeeper-3.5.4-beta/zookeeper…

(C++)CSP202009-1 称检测点查询

#include<cstdio> #include<cmath> #define MAXSIZE 200//定义结构体 struct sqList{int r[MAXSIZE1][2];int length0; }; //交换 void swap(sqList* sqz,int index1,int index2){int temp sqz->r[index1][1];sqz->r[index1][1]sqz->r[index2][1];sqz-&…

sysbench的安装和做性能测试

sysbench的安装和做性能测试 http://imysql.cn/node/312 sysbench是一个模块化的、跨平台、多线程基准测试工具&#xff0c;主要用于评估测试各种不同系统参数下的数据库负载情况。 关于这个项目的详细介绍请看&#xff1a;http://sysbench.sourceforge.net。 它主要包括以下几…

React文档 state and lifecycle

状态和生命周期 这篇介绍 React 组件中状态和声明周期的概念。详情可以查看API参考 。 思考前一部分中时钟的例子。渲染元素中&#xff0c;我们仅学习了一种更新 UI 的方式。调用 ReactDOM.render() 改变渲染后的输出。 function tick() {const element (<div><h1>…

【讨论】基于WF的流程结构

大家都知道&#xff0c;在WF中默认情况下&#xff0c;其活动是以树状结构组成的&#xff0c;简单说就是复合活动包含其子活动&#xff0c;如果子活动也是复合活动也可以包含其子活动&#xff0c;但同一个活动不能成为两个活动的子活动。这种方式被大量使用在WF自带的活动库中&a…