Как подключиться к FTP-серверу с помощью сокетов? - PullRequest
0 голосов
/ 01 мая 2018

Я пытаюсь создать простой FTP-клиент, но каким-то образом не удается установить FTP-соединение.

Я использовал следующий код:

import socket 
sock = socket.socket() 
sock.connect(('localhost', 21)) 
data = 'USER adm\r\n'.encode() 
sock.send(data) 
print('Close') 
sock.close() 

Журналы FTP-сервера, который я пытаюсь подключить, выглядят так:

(048507) 01.05.2018 06:00:03 - (не авторизован) (127.0.0.1)> Подключено к порту 21, отправка приветственного сообщения ...
(048507) 01.05.2018 06:00:03 - (не авторизован) (127.0.0.1)> 220-FileZilla Server 0.9.60 бета
(048507) 01.05.2018 06:00:03 - (не зарегистрирован) (127.0.0.1)> 220-написанный Тимом Коссе (tim.kosse@filezilla-project.org)
(048507) 01.05.2018 06:00:03 - (не авторизован) (127.0.0.1)> 220 Пожалуйста, посетите https://filezilla -project.org /
(048507) 01.05.2018 06:00:03 - (не авторизован) (127.0.0.1)> отключен.

Я пытался отправить команду USER adm, но не могу найти ее в журналах. Как мне установить успешное соединение с FTP-сервером через сокеты?

1 Ответ

0 голосов
/ 01 мая 2018

Есть несколько возможных проблем с синхронизацией.

FTP - это протокол "сервер говорит первым". Баннер 220, который вы видите в своем журнале, отправляется сервером сразу после подтверждения соединения. Клиент должен прочитать этот баннер перед отправкой каких-либо команд. (Если вы получили какой-либо числовой код, отличный от 220, сервер не хочет говорить.)

В целях тестирования я рекомендую вам прочитать с сервера и распечатать все, что вы прочитали, в stdout. Баннер 220 вашего сервера является примером многострочного ответа FTP, в котором за числовым кодом следует дефис в первой строке и после пробела в последней строке. Вы должны продолжать читать, пока не получите строку с пробелом после числового кода.

Если вы этого не сделаете и просто отправите USER сразу после завершения соединения, вы говорите вне очереди. В зависимости от того, насколько быстро работает ваш клиентский код, сервер может получить команду раньше, чем он ее ожидает, и это может объяснить, почему он не отвечает.

Другая возможная проблема заключается в том, что вы закрываете соединение сразу после отправки USER, не ожидая ответа. Сервер тоже может это заметить. Даже если он не пытается обнаружить нечетное поведение клиента, он может получить ошибку записи, когда пытается отправить свой ответ, и это может объяснить, почему он не ведет нормальный журнал.

Общая структура FTP-клиента в псевдокоде

connect
read response (banner)
while not done:
    send command
    read response
send QUIT
read response
close

(Это исключает действительно интересную часть, которая управляет подключением к данным, но вы еще не дошли до этого).

Для вашего теста, где вы просто хотите добраться до USER, вам по крайней мере необходимо:

connect
read banner
send USER
read response
close

(Пропуск QUIT, вероятно, не принесет вреда)

Обратите внимание, что серверу разрешено возвращать многострочный ответ на любую команду, включая USER, поэтому вы всегда должны проверять пробел после числового кода. Рекомендуется написать подпрограмму для чтения одного ответа FTP и вызывать его после каждой команды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...