我连接的web浏览器到stdin
并在SSH连接的远程端运行的命令的stdout
。这听起来像是你正在尝试做类似的事情:将套接字连接到运行在远程计算机上的程序,以便客户端可以连接到主机/端口并使用所述远程程序。
您需要做的第一件事就是建立一个SSH连接。我在子进程中使用外部程序ssh
(取决于操作系统的ssh
或plink
)。你可以使用类subprocess.Popen
来做到这一点。子进程启动(外部)ssh
应用程序以连接到远程主机并运行所需的命令。然后在那里听着它的“标准输入”并愿意回复它的“标准输出”。
(你可能使用Python SSH实现如的paramiko这里)
在一个非常高的水平(其中remote_command
是在远端运行的东西):
import subprocess
command = ['ssh', '[email protected]', 'remote_command']
sproc = subprocess.Popen(command, shell=False,
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
这留给你一个子进程,你可以通过它的stdin
,stdout
和stderr
进行交互。
获得此位先工作。
接下来你需要的是绑定一个套接字,监听并接受一个连接。然后从客户端读取并写入服务器。我写了一个轻量级的Socat
(由Socat启发)类:
import socket
class Socat(object):
EOT = '\004\r\n'
def __init__(self, binding, stream, eot = EOT):
self.stream = stream
self.eot = eot
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.bind(binding)
self.socket.listen(5)
while True:
print "waiting for connection"
(clientsocket, address) = self.socket.accept()
print "connection from %s:%s" % address
data = clientsocket.recv(1024)
self.stream.write(data)
while data:
data = self.stream.readline()
if data:
print "read %s bytes" % len(data)
if data == self.eot:
print "read termination signature"
clientsocket.close()
data = None
else:
clientsocket.send(data)
您应该套接字读了起来:this和this是有用的在这里。
然后,您可以使用此连接到您的remote_command
:
Socat(('localhost', 8080), sproc)
有些失位
你会注意到socat
类需要在stream
(不像我的例子),其有write
和readline
方法。我实际上将SSH连接封装在一个班级中,但我会将其作为练习给读者!
(基本上包含sproc
并提供write
和readline
方法class Stream
- 有效sproc.stdin.write()
和sproc.stdout.readline()
- !你的想法)
此外,您还需要一个协议,允许remote_command
信号传输的结束。我使用ASCII EOT
字符,我的远程程序在响应结束时发送。 socat
使用它来关闭客户端连接并接受新连接。根据您的使用情况,您需要提出适用于您的协议。
最后
上述所有可以改进。以上是我第一次削减,因为它很容易看到内部工作。我已经将它扩展为在线程中运行接受循环,并优雅地处理断开连接等。
但希望以上是合理的出发点。
你想要做的是相当明智的。你可能想研究'pexpect'模块。它是为这种事情量身定做的:驾驶交互式应用程序。请参阅https://pexpect.readthedocs.io/en/stable/overview.html以取得良好开端。它还有能力在你期待响应但没有响应的情况下在你的交互中放置超时。 –