通过Python和SSH连接的开放端口进行TCP-IP通信
这是一个关于在Python中使用TCP通信的新手问题。我想通过SSH隧道和Python的socket模块,在两个*类Unix系统之间建立TCP通信。我参考了这个Python MOTW网站上的前两个例子:“回声服务器”和“回声客户端”:http://www.doughellmann.com/PyMOTW/socket/tcp.html。
在同一个*类Unix系统(HOST1)上,通信运行得很好,但通过SSH隧道时就失败了。
我用命令ssh -L 10000:HOST2:10000 USERNAME@HOST2
登录到第二个*类Unix系统。然后我尝试以相同的方式建立通信,在HOST2上启动服务器的Python脚本,在HOST1上启动客户端的脚本。结果我在错误输出中看到了这个:
python test_socket_client.py
connecting to localhost port 10000
Traceback (most recent call last):
File "test_socket_client.py", line 10, in <module>
sock.connect(server_address)
File "<string>", line 1, in connect
socket.error: [Errno 111] Connection refused
当我在HOST1和HOST2上反过来启动服务器和客户端时,我也得到了同样的信息。
我到底哪里出错了呢?
2 个回答
我建议你先确认一下你的服务器是否在服务器主机上正常工作,同时确保你的ssh客户端在客户端主机上也在运行。你可以通过运行 netstat -tnlp
来检查这些情况。
你确定在运行客户端的时候,ssh客户端还是打开的吗?你可以选择在一个终端运行ssh,在另一个终端运行你的客户端,或者使用 ssh -Nf
这个命令,这样ssh在认证成功后会自动转到后台运行。
你的服务器把它的插座绑定到了localhost:10000,这意味着它只会接收来自本地的连接。SSH命令行的作用是把本地连接到10000端口的请求,转发到HOST2的10000端口。你的Python客户端程序连接到localhost:10000,而SSH连接的远端会尝试连接到HOST2:10000。虽然这两个端口和机器是一样的,但它们是不同的接口,你的插座并没有监听这个接口。
你可以把SSH命令改成ssh -L 10000:localhost:10000 USERNAME@HOST2
,或者把服务器的监听插座绑定到所有接口上:server_address = ('', 10000)
。这里的空字符串表示可以接收任何地址的连接。
当然,Gary van der Merwe说的没错:在你在HOST1上运行Python客户端程序时,SSH必须是正在运行的。