python 通过套接字进行管道子进程 I/O
我知道那里有类似的问题,但我在这个具体的例子中遇到了麻烦,并且还没有找到一个好的答案。我正在尝试为 dar 设置远程备份服务器,沿着这些线< /a>.我问了一个关于通过使用 subprocess.Popen 调用 netcat 来执行此操作的单独的问题,但我更愿意设置如果可能的话,使用 python 进行所有管道连接。将会有几场演出被转移,所以我不能先读取所有的输入,然后再传递。
问题是服务器似乎没有读取数据。
目前,我有以下代码:
from socket import socket, AF_INET, SOCK_STREAM
import sys
import SocketServer
import subprocess
class DarHandler(SocketServer.BaseRequestHandler):
def handle(self):
print('entering handler')
data = self.request.recv(1024).strip()
print('got: ' + data)
if data == 'xform':
s = socket(AF_INET, SOCK_STREAM)
s.bind(('',0))
myaddr, myport = s.getsockname()
print('bound new socket to {0}:{1}'.format(myaddr, myport))
self.request.send(str(myport))
s.listen(1)
conn, remoteaddr = s.accept()
print('accepted connection from {0}:{1}'.format(*remoteaddr))
xform_input = conn.makefile('rb',0)
proc = subprocess.Popen(
['/usr/bin/dar_xform', '-s', '10k', '-', 'archives/sockbackup',],
stdin=xform_input
)
return_code = proc.wait()
print('dar_xform returned {0}'.format(return_code))
conn.close()
self.request.send(str(return_code))
else:
self.request.send('bad request')
print('send result, exiting handler')
server_address = ('localhost', 18010)
def server():
server = SocketServer.TCPServer(server_address, DarHandler)
print('listening')
server.serve_forever()
def client():
sock = socket(AF_INET, SOCK_STREAM)
print('connecting to server')
sock.connect(('localhost', 18010))
print('connected, sending request')
sock.send('xform')
print('waiting for response')
port = sock.recv(1024)
print('got: ' + port)
s = socket(AF_INET, SOCK_STREAM)
s.connect(('localhost', int(port)))
print('connected to dar_xform port')
dar_output = s.makefile('wb',0)
return_code = subprocess.call(
['/usr/bin/dar', '-B', 'config/test.dcf', '-c', '-',],
stdout=dar_output
)
print('dar returned {0}'.format(return_code))
s.close()
result = sock.recv(1024)
print('received: ' + result)
sock.close()
print('socket closed, exiting')
if __name__ == "__main__":
if sys.argv[1].startswith('serv'):
server()
else:
client()
当我运行客户端时,我从服务器端得到以下输出:
listening entering handler got: xform bound new socket to 0.0.0.0:41658 accepted connection from 127.0.0.1:42440
然后它就坐在那里。同时, dar 运行在客户端上,客户端陷入等待服务器响应的状态:
connecting to server connected, sending request waiting for response got: 41300 connected to dar_xform port -------------------------------------------- 53 inode(s) saved with 0 hard link(s) recorded 0 inode(s) changed at the moment of the backup 0 inode(s) not saved (no inode/file change) 0 inode(s) failed to save (filesystem error) 1 inode(s) ignored (excluded by filters) 0 inode(s) recorded as deleted from reference backup -------------------------------------------- Total number of inodes considered: 54 -------------------------------------------- EA saved for 0 inode(s) -------------------------------------------- dar returned 0
I know there are similar questions out there, but I'm having trouble with this concrete example, and haven't found a good answer. I'm trying to set up a remote backup server for dar, along these lines. I've asked a separate question about doing this by invoking netcat with subprocess.Popen, but I'd prefer to set up the sockets and do all the piping with python if possible. There will be several gigs transferred, so I can't just read all the input first and then pass it on.
The problem is that the server doesn't seem to be reading the data.
At the moment, I've got the following code:
from socket import socket, AF_INET, SOCK_STREAM
import sys
import SocketServer
import subprocess
class DarHandler(SocketServer.BaseRequestHandler):
def handle(self):
print('entering handler')
data = self.request.recv(1024).strip()
print('got: ' + data)
if data == 'xform':
s = socket(AF_INET, SOCK_STREAM)
s.bind(('',0))
myaddr, myport = s.getsockname()
print('bound new socket to {0}:{1}'.format(myaddr, myport))
self.request.send(str(myport))
s.listen(1)
conn, remoteaddr = s.accept()
print('accepted connection from {0}:{1}'.format(*remoteaddr))
xform_input = conn.makefile('rb',0)
proc = subprocess.Popen(
['/usr/bin/dar_xform', '-s', '10k', '-', 'archives/sockbackup',],
stdin=xform_input
)
return_code = proc.wait()
print('dar_xform returned {0}'.format(return_code))
conn.close()
self.request.send(str(return_code))
else:
self.request.send('bad request')
print('send result, exiting handler')
server_address = ('localhost', 18010)
def server():
server = SocketServer.TCPServer(server_address, DarHandler)
print('listening')
server.serve_forever()
def client():
sock = socket(AF_INET, SOCK_STREAM)
print('connecting to server')
sock.connect(('localhost', 18010))
print('connected, sending request')
sock.send('xform')
print('waiting for response')
port = sock.recv(1024)
print('got: ' + port)
s = socket(AF_INET, SOCK_STREAM)
s.connect(('localhost', int(port)))
print('connected to dar_xform port')
dar_output = s.makefile('wb',0)
return_code = subprocess.call(
['/usr/bin/dar', '-B', 'config/test.dcf', '-c', '-',],
stdout=dar_output
)
print('dar returned {0}'.format(return_code))
s.close()
result = sock.recv(1024)
print('received: ' + result)
sock.close()
print('socket closed, exiting')
if __name__ == "__main__":
if sys.argv[1].startswith('serv'):
server()
else:
client()
I get the following output from the server side when I run the client:
listening entering handler got: xform bound new socket to 0.0.0.0:41658 accepted connection from 127.0.0.1:42440
Then it just sits there. Meanwhile, dar
runs on the client and the client is stuck waiting for a response from the server:
connecting to server connected, sending request waiting for response got: 41300 connected to dar_xform port -------------------------------------------- 53 inode(s) saved with 0 hard link(s) recorded 0 inode(s) changed at the moment of the backup 0 inode(s) not saved (no inode/file change) 0 inode(s) failed to save (filesystem error) 1 inode(s) ignored (excluded by filters) 0 inode(s) recorded as deleted from reference backup -------------------------------------------- Total number of inodes considered: 54 -------------------------------------------- EA saved for 0 inode(s) -------------------------------------------- dar returned 0
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试向
subprocess.Popen(...)
提供dar_xform
命令的完整路径,看看是否可以继续有问题。您所描述的内容看起来可疑地像PATH
问题,特别是因为它在 shell 提示符下工作。Try providing a full path to the
dar_xform
command tosubprocess.Popen(...)
and see if you continue to have a problem. What you've described looks suspiciously like aPATH
issue, especially since it works at the shell prompt.