Skip to main content
 首页 » 编程设计

python之防止 socket.getaddrinfo 'resolving' 不存在的数字主机名

2025年05月04日6pander-it

我正在使用 socket.getaddrinfo 检查主机名是否可解析,捕获 socket.gaierror 以检测错误的主机名。这工作正常,除了在某些系统上,像“12345”这样的字符串被“解析”为垃圾地址。

这里到底发生了什么,我该如何防止它发生?

Python 2.6.6 + CentOS 6.2 上的奇怪行为

Python 2.6.6 (r266:84292, Dec  7 2011, 20:48:22)  
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import socket 
>>> hostname = "12345" 
>>> socket.getaddrinfo(hostname, "22", socket.AF_INET, socket.SOCK_STREAM, socket.SOL_TCP) 
[(2, 1, 6, '', ('0.0.48.57', 22))] 

Python 2.7.2 + OS X 10.6 上的预期行为

Python 2.7.2 (v2.7.2:8527427914a2, Jun 11 2011, 15:22:34)  
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> hostname = "12345" 
>>> socket.getaddrinfo(hostname, "22", socket.AF_INET, socket.SOCK_STREAM, socket.SOL_TCP) 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
socket.gaierror: [Errno 8] nodename nor servname provided, or not known 

请您参考如下方法:

您的字符串被解析为 IP 地址。尝试 hostname="1",您会看到它解析为 0.0.0.1。这确实是一种奇怪的行为,手册上说:

inet_aton() 也接受少于三个点的字符串;有关详细信息,请参阅 Unix 手册页 inet(3)。

手册页说像这样的字符串被解释为 32 位值,直接存储到二进制地址中,无需任何字节重新排列。