草庐IT

图解DHCP协议,搞懂你的电脑 手机如何自动获取IP的

IT一指禅 2023-04-24 原文

大家好,我是IT售前工程师Bernie.

本文简要介绍下,在计算机网络中DHCP的技术原理,欢迎阅读。

我们知道,无论是手机、电脑、笔记本,还是其他智能终端,只要连上WIFI或者网线,就能够直接上网。当我们查看笔记本的IP信息时,就会显示当前设备的IP地址、网关地址、子网掩码等,这些信息是计算机网络中数据包中必须的,放在数据报头。

但是,我们并没有手动的配置上述信息。

设备的IP是怎么来的呢?

小伙伴们不妨查看下自己的笔记本Internet选项,不出意外的话就会显示“自动获得IT地址的默认配置”。其实,这些IP是通过DHCP服务器下发,自动获取的。

接下来,我们以简单办公场景讲一下DHCP服务的概念和技术原理。

什么是DHCP?

DHCP的英文全称是Dynamic Host Configuration Protocol,动态主机配置协议。

直白一点讲就是:计算机网络中,端设备可以在DHCP服务器上动态获得IP地址、子网掩码和网关地址,以便可以在网络中标注自己的身份,获得上网的资格。

比如一个局域网中,有一台pc和一部手机,双方都连接到路由器。那么,pc和手机都可以从路由器上得到IP地址、网关地址和子网掩码。在这里,路由器就是他们的dhcp服务器。

那么他们是如何获取IP地址的呢?这里要重点讲一下

DHCP服务原理

第1步:discover

当一台终端设备,插入网线或者连接WIFI时。在初始化阶段,它是没有IP地址的。那么这时第一个任务就是通过广播的形式寻找子网下的dhcp服务器。

我们知道,在计算机网络中任何一条数据包都是要包含源IP地址、目的IP地址的。这里就矛盾了,因为pc3发送广播消息的目的就是获取IP地址,它既不知道自己的IP地址应该是多少,也不知道dhcp服务器的地址是多少。

这里往往会给这个数据包赋值源IP为0.0.0.0,目的IP为255.255.255.255.

特别说明一点, 0.0.0.0并不是一个真正意义的IP地址,它其实是缺省路由,即:告诉对方我不知自己IP是多少,所以用0.0.0.0代替。

而255.255.255.255也不是一个严格意义的IP地址,它是限制广播地址,即:告诉同一个网段的所有端设备,这里的设备都注意啦!255.255.255.255是不能被路由器转发的,因为它本身并没有太多意义。

这个广播消息会被二层交换机发送到同一个vlan下的所有设备中,包括pc1、pc2、dhcp1和dhcp2。

第2步:offer

由于pc1和pc2是端设备,不具备dhcp的功能,他们会自动忽略这个广播消息,

dhcp server1和dhcp server2接收到IP地址获取的请求消息时,他们都会分配一个IP地址、网关地址和掩码等信息给pc3。

这时候,pc3就会接收到两套不同的IP信息,他们都可以正常使用。同一网段中有几个dhcp服务器,就会分配给pc3几套IP地址信息。

注意:这里不仅仅包含IP信息,还包含这个IP的使用期限,过了期限就会自动回收或者自动续期。比如:宽带路由器的dhcp租用周期最小1min,最大是两天,默认值为120min。

第3步:request

上面pc3一条广播得到了2套不一样的IP信息,显然它是不能全部霸占的,只能使用1套。于是,pc3会选取其中的一套(一般选择最先到达的那个)。比如IP1的先到达,pc3就会选择IP1作为自己的IP地址信息。

这样就结束了?

并没有!

因为dhcp server1并不知道自己提供的IP地址被选中了,同样,dhcp server2也不知道自己提供的IP地址被淘汰了。

所以需要pc3发一条广播消息告知自己的选择结果。

有的小伙伴可能会感到奇怪,明明pc3已经有了自己的IP了,为何数据报中还是用0.0.0.0.这是因为还没有得到确认,也不能发送单播告知dhcp server1,其他的dhcp server也要知道的。

第4步:ack

终于到了最后一步,这一步的工作就是确认。

当收到pc3的选择结果后,dhcp server1会更新自己的路由表和mac 地址映射表,同时也会发送一条确认消息给pc3。

由于dhcp2之前分配给pc3的IP地址落选了,那么,它将把IP回收,以便在后续分配给其他的接入设备。同时,也会更新自己的mac地址表和路由表。

总结

以上便是计算机网络终端设备获取DHCP服务的全过程,整个过程包含4个部分:discover、offer、request和ack。他们是层层递进、环环相扣的关系。

特别说明:DHCP服务器分配出去的IP是临时租用!一般情况下,只要不设置租用时间为infinite(永久租用),端设备需要在租期到达50%的时候,给dhcp server发送request数据包更新自己的租用时间。

文章出自:​IT一指禅​,如有转载本文请联系【IT一指禅】今日头条号。


有关图解DHCP协议,搞懂你的电脑 手机如何自动获取IP的的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  8. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  9. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

随机推荐