|
1 |
| -# 5_FTP_server |
| 1 | +## FTP сервер |
| 2 | + |
| 3 | +### Цель работы |
| 4 | + |
| 5 | +Научиться программно работать с файлами и файловой системой, читать, создавать, перемещать и передавать файлы по сети |
| 6 | + |
| 7 | +### Задания для выполнения |
| 8 | + |
| 9 | +Создать сервер, который предоставляет клиенту базовые возможности файлового менеджера по сети. Клиент после подключения к серверу должен иметь возможности просматривать список файлов и папок в рабочей директории сервера (рабочая директория - это специальная папка, к которой имеет доступ процесс сервера, но она отделена от парки с кодом сервера и от любых системных файлов), создавать и удалять в ней папки, создавать, копировать и переименовывать файлы. Также клиент может передать на сервер название и содержимое файла и сервер должен создать соответствующий файл в текущей директории. Кроме того, клиент может запросить содержимое любого файла и сервер должен передать его в ответ. |
| 10 | + |
| 11 | +### Методические указания |
| 12 | + |
| 13 | +Для выполнения этой работы вам пригодится код многопоточного сервера, который вы создавали на предыдущих работах. Также следует воспользоваться средствами стандартной библиотеки Python, а именно модулями: os, shutils, subprocess. |
| 14 | + |
| 15 | +При проектировании сервера необходимо заранее определить формат запросов, которые может совершать пользователь. Так как он может выполнять разные действия, нужно предусмотреть, как это указывается в запросе. Фактически, вам нужно придумать набор команд. Причем, многие такие команды требуют передачи дополнительной информации. Рекомендуется использовать следующий набор команд: |
| 16 | + |
| 17 | +1. Посмотреть содержимое папки; |
| 18 | +2. Создать папку; |
| 19 | +3. Удалить папку; |
| 20 | +4. Удалить файл; |
| 21 | +5. Переименовать файл; |
| 22 | +6. Скопировать файл с клиента на сервер; |
| 23 | +7. Скопировать файл с сервера на клиент; |
| 24 | +8. Выход (отключение клиента от сервера); |
| 25 | + |
| 26 | +Для примера вы можете использовать формат соответствующих команд из интерпретатора bash или придумать собственные названия. |
| 27 | + |
| 28 | +Для начала работы необходимо создать просто сервер. Парадигма клиент-серверного взаимодействия подразумевает, что обычно клиент, присоединяясь к серверу, посылает ему сообщение-запрос. Сервер обрабатывает этот запрос и посылает ответ клиенту. После этого соединение закрывается. Это самая простая и распространенная схема. Мы будем использовать именно ее. |
| 29 | + |
| 30 | +```python |
| 31 | +PORT = 9090 |
| 32 | + |
| 33 | +sock = socket.socket() |
| 34 | +sock.bind(('', PORT)) |
| 35 | +sock.listen() |
| 36 | + |
| 37 | +while True: |
| 38 | + print("Слушаем порт", PORT) |
| 39 | + conn, addr = sock.accept() |
| 40 | + print(addr) |
| 41 | + |
| 42 | + request = conn.recv(1024).decode() |
| 43 | + print(request) |
| 44 | + |
| 45 | + response = process(request) |
| 46 | + conn.send(response.encode()) |
| 47 | + |
| 48 | +sock.close() |
| 49 | +``` |
| 50 | + |
| 51 | +Обратите внимание, что мы отделяем сетевую часть нашего приложения от логики обработки запроса. Это позволяет более просто развивать и модифицировать наше приложение. |
| 52 | + |
| 53 | +Задание лабораторной заключается в написании сервера. Однако, для целей отладки напишем простой клиент. Он будет в вечном цикле читать команду со стандартного входа, направлять ее серверу, печатать ответ: |
| 54 | + |
| 55 | +```python |
| 56 | +HOST = 'localhost' |
| 57 | +PORT = 9090 |
| 58 | + |
| 59 | +while True: |
| 60 | + sock = socket.socket() |
| 61 | + sock.connect((HOST, PORT)) |
| 62 | + |
| 63 | + request = input('myftp@shell$ ') |
| 64 | + sock.send(request.encode()) |
| 65 | + |
| 66 | + response = sock.recv(1024).decode() |
| 67 | + print(response) |
| 68 | + |
| 69 | + sock.close() |
| 70 | +``` |
| 71 | + |
| 72 | +Конечно, вы можете воспользоваться наработками предыдущих лабораторных работ и использовать динамическое назначение порта, логирование в файл, выход по команде, авторизацию и многие другие возможности. Часть из них приведена в дополнительных заданиях. |
| 73 | + |
| 74 | +Теперь мы можем написать функцию обработки запроса. Реализуем две самые простые функции нашего сервера: |
| 75 | + |
| 76 | +```python |
| 77 | +def process(req): |
| 78 | + if req == 'pwd': |
| 79 | + return os.getcwd() |
| 80 | + elif req == 'ls': |
| 81 | + return '; '.join(os.listdir()) |
| 82 | + else: |
| 83 | + return 'bad request' |
| 84 | +``` |
| 85 | + |
| 86 | +Остальные функции попробуйте реализовать самостоятельно. |
| 87 | + |
| 88 | +### Дополнительные задания: |
| 89 | + |
| 90 | +1. Ограничьте возможности пользователя рамками одной определенной директории. Внутри нее он может делать все, что хочет: создавать и удалять любые файлы и папки. Нужно проследить, чтобы пользователь не мог совершить никаких действий вне пределов этой директории. Пользователь, в идеале, вообще не должен догадываться, что за пределами этой директории что-то есть. |
| 91 | +2. Добавьте логирование всех действий сервера в файл. Можете использовать разные файлы для разных действий, например: подключения, авторизации, операции с файлами. |
| 92 | +3. Добавьте возможность авторизации пользователя на сервере. |
| 93 | +4. Добавьте возможность регистрации новых пользователей на сервере. При регистрации для пользователя создается новая рабочая папка (проще всего для ее имени использовать логин пользователя) и сфера деятельности этого пользователя ограничивается этой папкой. |
| 94 | +5. Реализуете квотирование дискового пространства для каждого пользователя. |
| 95 | +6. Реализуйте учётную запись администратора сервера. |
| 96 | +7. Напишите отладочный клиент. Клиент должен подключаться к серверу и в автоматическом режиме тестировать корректность его работы. Используйте подход, аналогичный написанию модульных тестов. Клиент должен вывести предупреждающее сообщение, если сервер работает некорректно. |
0 commit comments