ПРОТОКОЛ ОБМЕНА В ПРОЕКТЕ "ФАЙЛОВЫЙ СЕРВЕР"
Реализован простой файловый сервер, позволяющий просматривать
список файлов в текущей директории, изменять текущую директорию,
пересылать файлы серверу и получать файлы от сервера.
Для передачи данных используется протокол TCP.
Протокол обмена построен над протоколом TCP.
Данные передаются кадрами. Кадр содержит
1) команду, которая представляется целым числом (4 байта);
2) длину поля данных (целое число, 4 байта);
3) данные -- массив байтов переменной длины.
Длина поля данных может быть равна нулю и не может превышать
константы
const int FSR_MAXDATALEN = 2048;
Структура, описывающая кадр данных:
struct ProtocolFrame {
int command; // Protocol action
int length; // Length of data field
char data[FSR_MAXDATALEN]; // Various length field
};
Возможны следующие команды (все определения содержатся в
заголовочном файле "filesrv.h"):
const int FSR_SUCCESS = 0; // Command is performed successfully
const int FSR_ERROR = 1; // Cannot perform a command
const int FSR_READY = 2; // Server is ready
const int FSR_DATA = 3; // Block of data, next block follows
const int FSR_DATAEND = 4; // Last block of data
const int FSR_PUT = 5; // Put a file
const int FSR_GET = 6; // Get a file
const int FSR_PWD = 7; // Pring Work Directory
const int FSR_CD = 8; // Change directory
const int FSR_LS = 9; // List a directory contents
const int FSR_LOGOUT = 10; // End a session
const int FSR_MGET = 11; // Get a set of files (Multiple get)
Имена файлов во всех командах протокола передаются
в кодировке Unicode UTF-16, в которой каждый символ записывается
двумя байтами в формате Little Endian.
ОПИСАНИЯ КОМАНД
FSR_SUCCESS
Передается от сервера к клиенту
и означает успешное завершение запроса клиента.
Она передается при успешном завершении запросов
FSR_PUT и FSR_CD. Поле данных имеет нулевую длину.
FSR_ERROR
Передается от сервера к клиенту при ошибке.
Поле данных содержит текст, описывающий ошибку.
FSR_READY
Передается от сервера к клиенту и означает, что
сервер готов выполнить следующий запрос клиента.
FSR_DATA
Означает, что передается блок данных, который не
является последним, т.е. за ним обязательно будет
передан следующий блок. Кадр FSR_DATA может
передаваться как от клиента к серверу (например,
при выполнении команды FSR_PUT), так и от сервера
к клиенту (при выполнении команд FSR_GET и FSR_LS).
Поле length кадра содержит длину передаваемых данных
(она не может превышать константы FSR_MAXDATALEN = 2048).
FSR_DATAEND
Означает, что передается последний блок данных,
например, последняя порция содержимого файла или
последняя запись в листинге директории. В остальном
команда аналогична команде FSR_DATA. Прием клиентом кадра
FSR_DATAEND означает успешное завершение запроса клиента,
поэтому сервер в этом случае не передает команду FSR_SUCCESS.
FSR_PUT
Передается от клиента к серверу при запросе на передачу файла.
от клиента к серверу. Поле данных содержит имя файла
или путь к нему. По принятии этой команды сервер должен
ответить кадром FSR_READY, означающим, что он открыл
файл для записи и готов принимать содержимое файла,
или FSR_ERROR, если файл не может быть открыт для записи.
В первом случае клиент передает серверу
содержимое файла в серии кадров FSR_DATA,
заканчивающаяся кадром FSR_DATAEND. При успешной
передаче файла сервер по окончанию передачи отвечает командой
FSR_SUCCESS, при ошибке -- FSR_ERROR.
FSR_GET
Передается от клиента к серверу при запросе на прием файла
от сервера. Поле данных содержит имя файла
или путь к нему. Если такой файл существует на сервере
и открыт на чтение, то сервер в ответ передает клиенту
содержимое файла с помощью серии команд FSR_DATA,
заканчивающейся командой FSR_DATAEND. В противном случае
сервер отвечает командой FSR_ERROR. По окончанию передачи
файла (после блока FSR_DATAEND) сервер не передает команду
FSR_SUCCESS, поскольку сама по себе команда FSR_DATAEND
означает успешное завершение передачи.
FSR_PWD
(сокращение от Print Working Directory).
Передается от клиента к серверу и означает запрос полного
пути к текущей директории. Поле length кадра содержит
значение 0, т.е. данные в этой команде не передаются.
Сервер отвечает на запрос кадром FSR_DATAEND, поле данных
которого содержит путь к текущей директории на сервере.
FSR_CD
(сокращение от Change working Directory).
Передается от клиента к серверу и означает запрос на
изменение текущей рабочей директории сервера. Поле data
содержит путь к новой директории. Сервер отвечает кадром
FSR_SUCCESS в случае успешного выполнения команды или
FSR_ERROR в случае ошибки.
FSR_LS
(сокращение от List).
Передается от клиента к серверу и означает запрос на
получения содержимого текущей директории, т.е. списка
файлов и поддиректорий в текущей директории.
При ошибке (когда директория закрыта на чтение) сервер
передает клиенту кадр FSR_ERROR. В нормальной ситуации
(директория открыта на чтение) сервер в ответ
пересылает клиенту серию кадров FSR_DATA, заканчивающуюся
кадром FSR_DATAEND. Каждый кадр содержит запись ровно об
одном файле или поддиректории. Поле "data" кадра содержит:
в первых 4-х байтах -- аттрибуты файла или поддиректории,
соответствующие полю DWORD dwFileAttributes структуры
WIN32_FIND_DATA, используемой при перечислении
файлов в текущей директории в API Win32;
в байтах начиная с пятого (смещение 4) --
имя файла или поддиректории в кодировке UTF-16,
заканчивающеея нулевым символом.
FSR_MGET
Передается от клиента к серверу при запросе на прием множества
файлов от сервера. Поле данных содержит ШАБЛОН имени файла,
который может включать обычные символы и звездочку "*",
означающую произвольную подстроку, не содержащую разделителей
директорий "/". Протокол исполнения этой команды более сложен,
чем в случаях предыдущих команд, он подробно описан ниже.
ПРОТОКОЛ ВЫПОЛНЕНИЯ КОМАНДЫ FSR_MGET
Выполнение команды mget начинается с передачи кадра FSR_MGET
от клиента к серверу. Кадр FSR_MGET аналогичен кадру FSR_GET,
только вместо имени файла он содержит шаблон имени, который
может включать один или несколько символов "*", означающих
вхождение произвольной подстроки, не содержащей разделителей
директорий. В ответ сервер передает следующую информацию.
1. Если нет файлов, имена которых подходят под шаблон,
то сервер передает кадр FSR_DATAEND, в котором
поле длины содержит 0 (этот кадр означает завершение
списка имен файлов, подходящих под шаблон).
2. Если список файлов, имена которых подходят под шаблон,
непуст, то для каждого файла выполняется следующий обмен
данными меджу сервером и клиентом:
-- сервер передает клиенту кадр FSR_DATA, содержащий информацию
об очередном файле. Этот кадр подобен кадру, передаваемому
от сервера клиенту при выполнении команды FSR_LS,
он включает тип файла (который всегда равен DT_REG)
и имя файла, заканчивающеея нулевым байтом;
-- дальше сервер ожидает ответа от клиента. Ответом может быть
один из двух кадров:
FSR_READY, если клиент готов принять очередной файл
от сервера;
FSR_ERROR, если клиент не готов принять файл. В этом
случае выполнение команды FSR_MGET завершается.
-- если клиент ответил серверу командой FSR_READY, то сервер
передает клиенту содержимое файла так же, как и в случае
команды FSR_GET.
3. Для завершения передачи множества файлов сервер передает клиенту
кадр FSR_DATAEND, в котором поле длины содержит 0.