gethostname() 返回正确的主机名,bind() 不接受
我在做一个关于Python套接字的教程,整个代码如下:
import socket as so
s = so.socket()
host = so.gethostname()
port = 12345
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
print 'Got connection from', addr
c.send('Thank you for connecting')
c.close()
然后出现了错误信息:
Traceback (most recent call last):
File "server.py", line 13, in <module>
s.bind((host, port))
File "/Users/solid*name*/anaconda/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.gaierror: [Errno 8] nodename nor servname provided, or not known
打印主机名时我得到了:
super*name*
这实际上是我电脑的主机名,不过我觉得它的后面应该有“.local”。实际上,如果后面加上.local,s.bind()就能正常工作。那为什么没有呢?
我的系统是Mac OS X 10.7.5,使用的是Python 2.7.6,环境是Anaconda 2.0.0(x86_64)。
1 个回答
2
来自socket
模块文档的内容:
如果你在IPv4或IPv6的socket地址中使用主机名,程序可能会表现得不太稳定,因为Python会使用DNS解析返回的第一个地址。这个socket地址会根据DNS解析的结果和主机的配置,转换成不同的实际IPv4或IPv6地址。为了让程序行为更稳定,建议在host部分使用数字地址。
绑定socket的常见方法是绑定到所有网络接口,可以使用''
或'0.0.0.0'
(针对IPv4)这两种方式。这相当于C语言中的常量INADDR_ANY
:
s.bind(('', port))
这样你就不需要担心主机名或当前网络接口的地址等问题了。只有在比较特殊的情况下,比如你想绑定到特定的网络接口(例如在有多个网卡的主机上),你才需要在调用bind()
时指定地址;在这种情况下,你需要找出你想要的网络接口的数字IP地址,并把它传递进去。