
- •Программирование в локальных сетях с использованием почтовых слотов
- •1 Почтовые слоты
- •1.1 Имена почтовых ящиков
- •1.2 Размеры сообщений
- •1.3 Общие сведения об архитектуре клиент-сервер
- •1.4 Сервер почтовых ящиков
- •1.5 Клиент почтовых ящиков
- •1.6 Дополнительные api-функции почтовых ящиков
- •1.7 Неспособность отменить блокирующие запросы ввода-вывода
- •1.8 Утечки памяти
- •2 Задания на выполнение лабораторной работы.
- •3 Контрольные вопросы
1.5 Клиент почтовых ящиков
Для реализации клиента нужно разработать приложение, ссылающееся на существующий почтовый ящик и записывающее в него данные. В базовом клиентском приложении необходимо выполнить следующие шаги.
1. Открыть описатель-ссылку на почтовый ящик, в который нужно отправить данные, с помощью API-функции CreateFile.
2. Записать данные в почтовый ящик, вызвав API-функцию WriteFile.
3. Закрыть описатель почтового ящика с помощью API-функции CloseHandle.
Как уже говорилось, клиенты почтовых ящиков соединяются с серверами без установления соединения. Когда клиент открывает описатель-ссылку на почтовый ящик, он не устанавливает связь с сервером почтового ящика. На почтовые ящики ссылаются путем вызова API-функции CreateFile, определенной следующим образом:
HANDLE CreateFile(
LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes.
HANDLE hTemplateFlle
);
Параметр lpFileName описывает один или несколько почтовых ящиков, в которые можно поместить данные. Для этого укажите имя ящика в одном из форматов. Правила именования почтовых ящиков таковы:
\\.\mailslot\имя - определяет локальный почтовый ящик на том же компьютере;
\\имя_cepвepa\mailslot\имя - определяет удаленный сервер почтового ящика с именем имя_сервера;
\\имя_домена\mailslot\имя - определяет все почтовые ящики с именем имя в домене имя_домена;
\\*\mailslot\имя - определяет все почтовые ящики с именем имя в основном домене системы.
Параметр dwDesiredAccess должен иметь значение GENERIC _WRITE, потому что клиент может только записывать данные на сервер.
Параметр dwShareMode обязан иметь значение FILE_SHARE_READ, позволяя серверу открывать и выполнять операции чтения из почтового ящика.
Значение параметра lpSecurityAttributes не влияет на почтовые ящики - следует задать NULL.
Флаг dwCreationDisposition должен быть равен OPEN_EXISTING.
Это удобно, когда клиент и сервер функционируют на одном и том же компьютере. Если сервер не создал почтовый ящик, API-функция CreateFile вернет ошибку. Параметр dwCreationDisposition не имеет значения, если сервер работает удаленно.
Параметр dwFlagsAndAttributes должен иметь значение FILE_ATTRIBU-TE_NORMAL, a hTemplateFile - значение NULL.
После успешного создания описателя можно помещать данные в почтовый ящик. Клиент может только записывать данные в почтовый ящик с помощью Win32-функции WriteFile:
BOOL WrlteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
Параметр hFile - это описатель-ссылка, возвращаемый функцией CreateFile.
Параметры lpBuffer и nNumberOfBytesToWrite определяют, сколько байт будет отправлено от клиента серверу. Параметр lpNumberOfBytesWritten возвращает количество байт, отправленных серверу после завершения функции WriteFile.
Параметр lpOverlapped позволяет записывать данные в почтовый ящик асинхронно. Поскольку почтовые ящики обмениваются данными без установления соединения, функция WriteFile не блокирует ввод-вывод. На клиенте этот параметр должен быть равен NULL.