我正在尝试用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。
当可能打开多个网络接口时,您将使用一个巧妙的技巧来获取服务器的“真实”地址。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)