ПРОТОКОЛ ОБМЕНА В ПРОЕКТЕ "ФАЙЛОВЫЙ СЕРВЕР"

Реализован простой файловый сервер, позволяющий просматривать
список файлов в текущей директории, изменять текущую директорию,
пересылать файлы серверу и получать файлы от сервера.
Для передачи данных используется протокол 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.