Python socket.gethostname

Arr*_*lex 3 python sockets

我正在尝试用python编写小型Web服务器的代码以捕获HTTP帖子。但是我的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
Run Code Online (Sandbox Code Playgroud)

如果我改变

serversocket.bind((socket.gethostname(), 8089))
Run Code Online (Sandbox Code Playgroud)

serversocket.bind(("localhost", 8089))
Run Code Online (Sandbox Code Playgroud)

一切都可以通过telnet进行,但是我需要能够从Internet上的其他Web服务器进行连接,因此我需要使用socket.gethostname,但这会阻塞我的telnet。

tde*_*ney 6

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

hostname = socket.gethostname()
dns_resolved_addr = socket.gethostbyname(hostname)
serversocket.bind((dns_resolved_addr, 8089))
Run Code Online (Sandbox Code Playgroud)

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

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

在我的机器上,当我执行步骤时,

>>> socket.gethostbyname(socket.gethostname())
'127.0.1.1'
Run Code Online (Sandbox Code Playgroud)

请注意,这是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'
Run Code Online (Sandbox Code Playgroud)