Курсов проект № 1 по “Интернет програмиране с Java”
1.4. UDP-based File Client/Server
Автор: Светлин Наков
Версия: 0.9
Последна промяна: 18.03.2004
Да се напише програма на Java, която използвайки възможностите на пакета java.net реализира прост файлов сървър. Да се напише и програма-клиент за този сървър. Клиентът и сървърът трябва да си комуникират само по протокол UDP. Не е разрешено да се използват TCP сокети.
Сървърът
Сървърът трябва да дава възможност на потребителя да вижда файловете зададена директория и да изтегля файлове. Трябва да се поддържа едновременна работа на повече от един клиент. Например докато един клиент тегли голям файл (което може да отнеме часове) другите клиенти трябва да могат да изпълняват команди. Файловият сървър трябва да слуша на UDP порт 4444 и да изпълнява следните команди:
DIR path – извежда всички файлове в зададена директория, по един на ред, като за всеки файл се извежда името му и дължината му, а за всяка директория се извежда името й и <DIR> вместо дължина. Необходимо е да се извежда още и информация за името на поисканата директория, за броя на файловете и поддиректориите в нея и за общата дължина на показаните файлове. Форматът на изхода от командата DIR трябва да е оформен по следния начин:
клиент: |
DIR /home/nakov |
сървър: |
+Listing directory /home/nakov
.. <DIR> documents <DIR> inetjava <DIR> file1.txt 117 file3.zip 3225187 file2.doc 73812
Total 3 files (3299116 bytes), 2 subdirectories. |
С „/” се означава коренната директория на сървъра. Ако няма файлове и директории, списъкът трябва да е празен, а на последния ред трябва да пише “Total 0 files (0 bytes), 0 subdirectories”. Директорията е относителен път спрямо коренната директория на сървъра (Root directory). За улеснение може да се счита, че в имената на файловете и директориите няма интервали и специални символи (като ", ', :, /, \ и подобни). Специалната директория “..“ означава по-горната директория и се появява само ако има такава. Ако поисканата директория не съществува, трябва да се върне съобщение за грешка „-Invalid directory”. Ето пример за липсваща директория:
клиент: |
DIR /home/nakov/alabala |
сървър: |
-Invalid directory |
Не трябва да се позволява напускане на основната директория чрез трикове като „DIR ../”, „DIR ./../” или „DIR C:\”. Например:
клиент: |
DIR ../ |
сървър: |
-Invalid directory |
GET full_filename – ако сървърът не може да отвори за четене файла с име full_filename (например ако такъв файл не съществува), командата връща съобщение “-Invalid file”. Ако файлът се отвори успешно, сървърът връща размера и съдържанието на файла по следния образец:
клиент: |
GET /home/nakov/documents/nakov.jpg |
сървър: |
+OK. File contents follows: <file binary contents (filesize bytes)> |
Съдържанието на файла може и да не е текстово. Не трябва да се допуска извличане на файлове извън текущата директория с трикове като „GET ../index.asp” или “GET C:/windows/notepad.exe”. Директориите не се считат за файлове и не могат да се изтеглят. Ето пример:
клиент: |
GET / |
сървър: |
-Invalid file |
HELP – връща кратка помощна информация. Примерен резултат от командата:
клиент: |
HELP |
сървър: |
+Valid commands are: DIR path – Lists given directory GET full_filename – Retrieves given file (given with its full path) HELP – Displays this help |
Сървърът предполага, че клиентът е коректен и не изпраща неправилни команди и неправилни параметри на команди. Сървърът трябва да позволява няколко клиента да се обслужват едновременно без никой клиент да чака някой от останалите.
Клиентът
Клиентското приложение, което трябва да напишете, трябва да чака въвеждането на команда от конзолата, след което да я препраща към сървъра и да отпечатва резултата, върнат от сървъра. Ако сървърът не отговори за определено време (например 5 секунди), е необходимо клиентът да изпрати командата отново, а след три неуспешни опита да изведе съобщение за грешка „!No response from the server.”
Имайте предвид, че понякога отговорът на сървъра може да не се събира в един UDP пакет (например ако искаме да изтеглим 10MB файл) и затова е необходимо да осигурите механизъм за прехвърляне на обемна информация чрез последователност от UDP пакети. Трябва да се съобразявате с факта, че е понякога UDP пакети могат да се изгубват и че при UDP няма гаранция за запазване на наредбата на последователно изпратени пакети. Изгубените пакети трябва да се изпращат отново, освен ако не се изгубят 3 пакета подред, при което операцията се счита за неуспешна и се прекратява.
За улеснение на потребителя при получаване на файлове е необходимо при успешен отговор на сървъра на командата GET filename, върнатият файл да се записва автоматично в работната директория на клиента. Работната директория на клиента може да фиксирана (например C:\TEMP) или да се използва текущата директория (тази от която се стартира Java виртуалната машина).
Както за сървъра, така и за клиента, не е нужен графичен потребителски интерфейс! Достатъчно е да се напише конзолно приложение, което покрива описаната функционалност.