一、前言
在現代網絡編程中,獲取本機的網絡接口信息和 IP 配置是非常常見的需求。
例如:
- 開發一個需要選擇合適網卡的 網絡服務;
- 在多網卡環境下實現 流量路由與控制;
- 在系統診斷工具中展示 IP/MAC 地址、子網掩碼、默認網關;
- 編寫跨平臺工具時需要兼容 Linux、Windows、macOS 的網絡接口管理。
在 Python 標準庫中,雖然 socket
模塊提供了部分網絡功能,但缺乏直接、簡潔的方法來獲取 所有網卡與其詳細信息。
此時,netifaces
庫便成為一個非常實用的工具。
二、netifaces 簡介
1. 什么是 netifaces?
netifaces
是一個跨平臺的 Python 庫,用于枚舉網絡接口、獲取其地址(IPv4、IPv6、MAC)、子網掩碼、廣播地址以及默認網關信息。
它的特點是:
- 輕量級:安裝簡單,無需依賴復雜的第三方庫。
- 跨平臺支持:兼容 Linux、Windows、macOS 等。
- 功能專一:專注于 網卡與 IP 信息獲取,不提供網絡通信功能。
- 與 socket 模塊互補:socket 偏重通信,netifaces 偏重信息獲取。
2. 適用場景
- 系統監控工具:展示網絡接口信息。
- 自動化運維腳本:檢測并選擇可用 IP 地址。
- 分布式系統:在多網卡機器上自動綁定合適的網卡。
- 網絡診斷:輔助排查網絡配置問題。
三、安裝與快速體驗
1. 安裝
pip install netifaces
驗證安裝:
import netifaces
print(netifaces.interfaces())
2. 示例:獲取所有網絡接口
import netifacesinterfaces = netifaces.interfaces()
print("本機網絡接口列表:")
for iface in interfaces:print(iface)
在 Linux 機器上可能輸出:
本機網絡接口列表:
lo
eth0
wlan0
docker0
在 Windows 上可能輸出:
本機網絡接口列表:
{12345678-ABCD-90EF-1234-567890ABCDEF}
{11223344-5566-7788-99AA-BBCCDDEEFF00}
四、netifaces 核心 API
1. netifaces.interfaces()
返回本機所有網絡接口名稱。
2. netifaces.ifaddresses(interface)
返回指定接口的地址信息。
示例:
import netifacesinfo = netifaces.ifaddresses("eth0")
print(info)
輸出示例(Linux):
{17: [{'addr': '00:1a:2b:3c:4d:5e'}], # 鏈路層 (MAC)2: [{'addr': '192.168.1.100', 'netmask': '255.255.255.0', 'broadcast': '192.168.1.255'}], # IPv410: [{'addr': 'fe80::1a2b:3c4d:5e6f%eth0'}] # IPv6
}
3. netifaces.gateways()
獲取默認網關和所有接口的路由信息。
示例:
import netifacesgws = netifaces.gateways()
print(gws)
輸出示例:
{'default': {2: ('192.168.1.1', 'eth0')}, 2: [('192.168.1.1', 'eth0', True)],10: [('fe80::1', 'eth0', True)]
}
其中:
2
表示 IPv410
表示 IPv6
4. 地址族常量
netifaces.AF_INET
:IPv4netifaces.AF_INET6
:IPv6netifaces.AF_LINK
:MAC 地址
五、實戰案例
1. 獲取本機 IPv4 地址
import netifacesdef get_ipv4_address(interface):try:info = netifaces.ifaddresses(interface)return info[netifaces.AF_INET][0]['addr']except KeyError:return Nonefor iface in netifaces.interfaces():ip = get_ipv4_address(iface)if ip:print(f"{iface}: {ip}")
2. 獲取默認網關
import netifacesgws = netifaces.gateways()
default_gateway = gws['default'][netifaces.AF_INET][0]
print("默認網關:", default_gateway)
3. 判斷某接口是否有網絡
import socketdef check_internet(ip="8.8.8.8", port=53, timeout=3):try:socket.setdefaulttimeout(timeout)socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((ip, port))return Trueexcept Exception:return Falseprint("網絡是否可用:", check_internet())
4. 多網卡路由選擇
在有 eth0
和 wlan0
的機器上,自動選擇有公網 IP 的接口作為通信接口。
5. 網絡診斷工具
輸出類似 ifconfig
或 ip addr
的結果。
import netifacesfor iface in netifaces.interfaces():print(f"接口: {iface}")addrs = netifaces.ifaddresses(iface)if netifaces.AF_INET in addrs:for link in addrs[netifaces.AF_INET]:print(" IPv4:", link['addr'])if netifaces.AF_INET6 in addrs:for link in addrs[netifaces.AF_INET6]:print(" IPv6:", link['addr'])if netifaces.AF_LINK in addrs:for link in addrs[netifaces.AF_LINK]:print(" MAC:", link['addr'])
六、跨平臺注意事項
-
Linux
- 接口名為
eth0
,wlan0
,lo
等。 ifconfig
和ip addr
結果與 netifaces 一致。
- 接口名為
-
Windows
- 接口名為 GUID(長字符串),需額外處理。
- 可以使用
socket.gethostbyname(socket.gethostname())
輔助獲取本機 IP。
-
macOS
- 接口名為
en0
,en1
等。
- 接口名為
七、與其他庫對比
功能 | netifaces | psutil | socket |
---|---|---|---|
獲取網卡列表 | ? | ? | ? |
獲取 IPv4 / IPv6 | ? | ? | 部分 |
獲取 MAC 地址 | ? | ? | ? |
獲取默認網關 | ? | ? | ? |
跨平臺支持 | ? | ? | ? |
系統資源監控 | ? | ? | ? |
結論:
- 如果只需要網絡接口信息,推薦 netifaces。
- 如果需要更多系統信息(CPU、內存、網絡流量),推薦 psutil。
- 如果只是做網絡通信,使用 socket 即可。
八、進階應用
1. 自動綁定公網 IP
在分布式服務中,程序需要自動選擇公網 IP 進行注冊。
def get_public_ip():for iface in netifaces.interfaces():addrs = netifaces.ifaddresses(iface).get(netifaces.AF_INET, [])for addr in addrs:ip = addr['addr']if not ip.startswith("192.168.") and not ip.startswith("10."):return ip
2. 容器與虛擬機場景
在 Docker、VMware、KVM 等虛擬化環境中,機器可能有多個虛擬網卡。
netifaces
可以幫助我們區分 宿主機 IP 與 容器/虛擬機 IP。
3. 與 ZeroMQ 結合
在使用 pyzmq 進行分布式通信時,可以用 netifaces
自動選擇合適的網卡綁定。
九、性能與限制
1. 性能
- 純 C 擴展實現,性能開銷小。
- 僅用于查詢信息,不進行數據傳輸。
2. 限制
- 只讀操作:不能修改網卡配置。
- 接口名處理:在 Windows 上需轉換 GUID。
- 功能專一:只適合獲取接口與 IP 信息,不支持實時流量統計。
十、總結
netifaces
是一個小而美的 Python 庫,功能專注于 跨平臺獲取網絡接口信息。
通過它,我們可以:
- 獲取所有網卡、IP、MAC 地址;
- 查詢默認網關;
- 構建跨平臺的網絡診斷工具;
- 在多網卡環境中自動選擇合適的 IP 綁定。
與 psutil
相比,netifaces
更輕量、更專注;與 socket
相比,它提供了更高層次的接口抽象。
如果你正在開發 分布式系統、運維工具、網絡診斷應用,netifaces
無疑是一個非常值得掌握的工具。