【发布时间】:2013-09-20 15:20:25
【问题描述】:
我正在尝试创建一个侦听套接字的 Python 程序。我正在使用带有 Python 2.7 的 Windows 7。无论我做什么,套接字似乎都可以从本地机器访问,但不能从网络上的其他地方访问。
我有以下代码:
from werkzeug.wrappers import Request, Response
@Request.application
def application(request):
return Response('Hello World!')
if __name__ == '__main__':
from werkzeug.serving import run_simple
# Using empty string or the machine's real IP address here
# gives the same problem
run_simple('0.0.0.0', 4000, application)
如果我从本地计算机连接,我会看到响应正常。如果我执行
$ curl 'http://192.168.1.1:4000/'
从网络上的另一个(linux)机器上,curl 在超时之前挂了很长时间。 Wireshark 显示我收到一个到端口 4000 的 SYN 数据包,但没有看到它被确认。
我已经尝试确保允许到此端口的数据包通过防火墙(我在 Wireshark 中看到 SYN 的事实表明这不是问题)。我已经尝试将 Python 设置为以管理员身份运行(并且我检查了 ctypes.windll.shell32.IsUserAnAdmin() 是否返回 true)。这不仅仅是 Werkzeug,我也尝试过使用 Python 标准库中的 SocketServer。
在同一端口上运行 Windows Apache 可以在整个网络中正常工作,这表明网络或防火墙或我的 curl 请求没有问题。
netstat -an 显示:
TCP 0.0.0.0:4000 0.0.0.0:0 LISTENING
编辑:我尝试过使用以下最少的代码。在服务器端(Windows 7):
import socket
s = socket.socket()
s.bind(('', 8080))
s.listen(1)
remotesock, addr = s.accept()
在 linux 客户端上:
import socket
s = socket.socket()
s.connect('192.168.1.1', 8080)
这会挂起直到超时,就像 curl 一样。
【问题讨论】:
-
在防火墙完全未激活的情况下进行测试。
-
很遗憾,由于我公司 IT 部门应用的组策略,无法完全禁用防火墙。我最终可能会改变这一点,但鉴于我有一个允许访问所有端口的规则,并且考虑到 Apache 在同一端口上运行时可见,我看不出防火墙是如何出现问题的。
-
简单的调试步骤是打开 python 并创建一个侦听来自任何地方的连接的套接字。然后转到您的远程计算机,创建一个套接字,并将其连接到侦听器。这几乎是你能得到的准系统。如果您无法连接远程计算机,则说明您遇到了外部问题。 '导入套接字; s=socket.socket(); s.听(1); remotesock, addr = s.accept()' 然后在远程:'import socket; s=socket.socket(); s.connect(serveraddr, serverport)'
-
将
python.exe添加到firewall exception list。 -
因此,仅仅拥有允许所有 TCP 端口上的流量的防火墙规则似乎是不够的。我需要一个允许访问 Python.exe 的防火墙规则(我之前已经这样做了,但我最终只允许 python.exe 访问域网络)。恼人的。如果有人想把它写下来作为答案,我会投票给他们业力。 :-)