Задать вопрос
@Alons

Не удается скачать файл через socket, почему?

пытаюсь написать reverse shell, учусь еще...
ссылка на сервер
ссылка на клиент
Проблема в функции download в клиенте(предположительно). При ее вызове на сервер происходит загрузка файла, но файл остается не доступным пока не закроется сокет. Т.е. если в конце функции объявить s.close() то файл будет доступен, а клиент в последствии улетит с ошибкой в строке s.send(output.encode()).
Если сокет не закрывать то по выходу из функции download он впадает в бесконечный цикл не возвращая серверу ничего, но если убить скрипт то скачанный файл станет доступен...
Требуется что бы после закачки файл был доступен без явного закрытия сокета или шатдауна(в одну из сторон)... и конечно же клиент продолжил работать в штатном режиме продолжая выполнять дальнейшие команды. Вот только я никак не могу понять в чем моя ошибка и как мне осуществить задуманное?!?
  • Вопрос задан
  • 141 просмотр
Подписаться 1 Средний Комментировать
Решения вопроса 1
@galaxy
Основная проблема в tqdm. Нельзя одновременно использовать итератор
progress = tqdm.tqdm(range(filesize) ... for _ in progress:
и вручную обновлять прогресс, он будет глючить страшно (попробуйте, напишите простейший цикл:
r=tqdm.tqdm(range(100))
for i in r:
  sleep(1)
  r.update(10)

увидите, что будет.

tqdm глючит и не останавливает вовремя цикл приема на сервере. Когда файл полностью скачан, строчка bytes_read = client_socket.recv(BUFFER_SIZE) блокируется в ожидании новых данных и все виснет.
Вообще для блокирующих сокетов пустой результат recv - признак ошибки/закрытия соединения, если данных нет - recv() блокируется.

Вам надо или разобраться с tqdm, или считать длину полученных данных и прерывать цикл так:
if downloaded >= filesize:
  break


Ну и в теории, вот это стремный подход:
received = client_socket.recv(BUFFER_SIZE).decode()
filename, filesize = received.split(SEPARATOR)

Никто не гарантирует вообще-то, что то, что вы послали отдельными пакетами (отдельными send) придет также отдельными пакетами (т.е. надо будет принимать данные отдельными recv). Данные могут буферизоваться и прийти одним пакетом. И вы прочитаете мусор.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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