Python socket.gethostname

7

我正在尝试使用Python编写一个小型Web服务器来捕获HTTP POST请求。但是,在其中的socket.gethostname部分出现了问题。

以下是我的示例代码:

import socket

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind((socket.gethostname(), 8089))
serversocket.listen(1)


while True:
    connection, address = serversocket.accept()
    buf = connection.recv(164)
    print buf

如果我更改 <\p>
serversocket.bind((socket.gethostname(), 8089))

to

serversocket.bind(("localhost", 8089))

一切都很好,我可以通过telnet访问它,但我需要能够从另一个互联网上的Web服务器连接,因此我需要使用socket.gethostname,但这会阻止我的telnet。


是在互联网上的另一台Web服务器,还是只在您的局域网中? - OneCricketeer
还有,“我正在尝试使用Python编写一个小型Web服务器” - 你尝试过使用Flask吗? - OneCricketeer
在互联网上!?我现在会研究Flask。 - Arriflex
3
尝试使用serversocket.bind(("0.0.0.0", 8089)),这应该会将所有外部地址都绑定起来。 - tdelaney
1
我正在将树莓派配置为服务器,而socket.gethostname()只是简单地返回raspberrypi,哈哈。所以,大家要小心 :) - San Askaruly
显示剩余3条评论
1个回答

17

当可能有多个网络接口时,您正在使用巧妙的技巧来获取服务器的“真实”地址。 serversocket.bind((socket.gethostname(), 8089)) 可以分解为:

hostname = socket.gethostname()
dns_resolved_addr = socket.gethostbyname(hostname)
serversocket.bind((dns_resolved_addr, 8089))

您可以获取本地主机名,然后询问DNS以获取它认为您的IP地址是什么,并绑定到该地址。这就是外部连接将使用的IP地址,因此您也应该使用它。

但这并不总是有效的。DNS可能不知道您的服务器名称,或者您的服务器在DNS中有不同的名称。一个例子是我的家庭网络,我没有DNS服务器,由我的调制解调器分配的DHCP地址在任何地方都没有出现在名称服务器中。如果公司的DHCP没有在其本地DNS中注册您的主机名,则存在类似的问题。

在我的机器上,当我完成这些步骤时,我得到:

>>> socket.gethostbyname(socket.gethostname())
'127.0.1.1'

注意它是 127.0.1.1 ... 我想这是Ubuntu的一些奇怪方式,以避免其路由表混乱。无论如何,一种解决方案是尝试解析地址,如果您不喜欢它,请回退到默认值。

>>> my_ip = socket.gethostbyname(socket.gethostname())
>>> if my_ip.startswith('127.0.'):
...     my_ip = '0.0.0.0'
... 
>>> my_ip
'0.0.0.0'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接