4、动态IP地址配置:DHCP客户端配置、dhclient使用、租约管理

说实话,在嵌入式系统里配IP地址,我最怕的就是手动配。你想想看,产品一量产就是几百上千台,每台都得手动敲ifconfig?那不得疯掉。所以动态IP配置,也就是DHCP,几乎是所有网络设备的标配。

今天我们就来聊聊QNX下的DHCP客户端怎么玩。我会把我在几个车载项目里踩过的坑,一并抖出来。

4.1 DHCP客户端配置:从零开始

QNX的DHCP客户端,核心工具是dhclient。它不像Linux那样有复杂的NetworkManager,QNX走的是轻量级路线。说白了,就是一个守护进程,负责跟DHCP服务器讨价还价,拿到IP地址。

配置文件的路径是/etc/dhclient.conf。我第一次接触这个文件时,觉得它挺简洁的。来看个典型配置:

interface "eth0" {
    send host-name "my-qnx-device";
    send dhcp-client-identifier 01:aa:bb:cc:dd:ee:ff;
    request subnet-mask, broadcast-address, time-offset, routers,
            domain-name-servers, domain-name, interface-mtu;
    require subnet-mask, routers;
    timeout 30;
    retry 60;
    select-timeout 5;
    reboot 10;
    backoff-cutoff 120;
    initial-interval 2;
};

这里我解释几个关键点:

  • send host-name:告诉DHCP服务器你的设备名字。我在项目中遇到过,有些企业级交换机就靠这个做准入控制,名字不对直接不给IP。
  • request:你希望从服务器拿到哪些参数。我个人习惯把interface-mtu也加上,因为有些网络环境MTU不是1500,比如VPN隧道场景。
  • require:必须拿到的参数。如果服务器没给,dhclient会认为这次租约无效。我建议至少保留subnet-maskrouters,否则你拿到IP也上不了网。
  • timeout:第一次请求的超时时间。30秒够用了,但如果你在快速启动的场景,可以压到10秒。
我的小技巧: 在调试阶段,我会把timeout设成5秒,这样能快速知道DHCP服务器是不是在正常工作。等上线了再改回30秒。

4.2 dhclient使用:启动、停止与调试

配置写好了,怎么跑起来?很简单:

dhclient eth0

这条命令会启动dhclient,让它去跟服务器交互。如果你想指定配置文件:

dhclient -cf /path/to/my-dhclient.conf eth0

嗯,这里要注意:dhclient默认是前台运行的。如果你想让它后台跑,加个-b参数:

dhclient -b eth0

我曾经在调试一个车载网关时,发现dhclient老是莫名其妙退出。后来一查,原来是前台模式被SIGTERM给杀了。改用-b后台模式后,问题就解决了。

停止dhclient也很直接:

dhclient -r eth0

这个-r参数会释放当前租约,并通知DHCP服务器“我不用了”。我个人习惯在设备关机前执行一下这个操作,算是对网络资源的礼貌归还。

调试时,我最常用的参数是-d(debug模式):

dhclient -d eth0

它会打印出详细的交互过程,包括发送的报文、收到的响应、以及每一步的状态机变化。你想想看,如果DHCP拿不到IP,看这个输出基本就能定位问题。

4.3 租约管理:理解生命周期

DHCP的核心是租约。说白了,IP地址不是你的,是借给你的。租约到期了,你得续租,否则服务器就把IP收回去了。

租约文件默认存在/var/db/dhclient.leases。里面记录了每个接口的租约历史:

lease {
    interface "eth0";
    fixed-address 192.168.1.100;
    option subnet-mask 255.255.255.0;
    option routers 192.168.1.1;
    renew 4 2025/01/15 10:30:00;
    rebind 4 2025/01/15 11:00:00;
    expire 4 2025/01/15 11:30:00;
}

这里有三个时间点很重要:

时间点 含义 我的经验
renew 开始尝试续租的时间 一般是租期的一半。比如租期1小时,30分钟时就开始续租。
rebind 如果续租失败,开始广播寻找新服务器的时间 通常是租期的87.5%。这时候如果还没续上,说明原服务器可能挂了。
expire 租约到期,IP地址失效 一旦过期,dhclient会释放IP,然后重新开始请求。
注意: 如果租约过期了,但你的设备还在用这个IP,网络就会出问题。我曾经在测试中遇到过,设备一直ping通,但实际数据包已经发不出去了。原因就是租约过期,网关不认这个IP了。

手动查看当前租约状态,可以用:

dhclient -l eth0

这个命令会打印出当前接口的租约信息,包括IP地址、租期剩余时间等。我个人习惯在脚本里定期调用它,用来监控网络状态。

4.4 避坑指南:我踩过的几个雷

做嵌入式这么多年,DHCP相关的坑我踩了不少。挑几个典型的说说:

  • 租约文件权限问题:有一次我发现dhclient启动后一直报错,说无法写入租约文件。一查,原来是/var/db目录的权限不对。dhclient需要以root权限运行,但文件系统挂载成了只读。解决办法是确保/var/db可写,或者用-lf参数指定一个可写的路径。
  • 多网卡冲突:如果你的设备有多个网卡,比如eth0和eth1,dhclient默认只会处理第一个。我曾经在项目里同时配了两个网卡,结果eth0拿到了IP,eth1一直超时。后来发现是配置文件里只写了interface "eth0"。解决办法是每个网卡单独写一个配置段,或者用-i参数指定接口。
  • DHCP服务器响应慢:在有些工业网络里,DHCP服务器可能响应很慢,甚至丢包。我建议把timeout设得大一点,比如60秒。同时开启retry机制,让dhclient自动重试。
核心总结: DHCP配置看似简单,但租约管理是灵魂。理解renew、rebind、expire这三个时间点,你就能掌控整个动态IP的生命周期。别等到设备断网了才去查租约,那时候就晚了。

好了,这一章就聊到这儿。下一章我们会深入静态IP配置,看看什么时候该用静态,什么时候该用动态。说白了,没有银弹,只有最适合场景的方案。