Передача данных между процессами с помощью Mailslot
Mailslot - один из самых простых способов обмена данными между процессами, который работает еще со времен Windows 95. Каналы Mailslot позволяют передавать данные от одного или нескольких клиентов к одному или нескольким серверам, в том числе в широковещательном режиме. На локальном компьютере может быть один серверный процесс, но в сети или в домене может одновременно работать несколько серверов. Количество клиентских приложений не ограничено. Принцип работы Mailslot схож с работой электронной почты.Основным недостатком Mailslot является то, что серверное приложение не может достоверно знать, от какого процесса и с какого компьютера было отправлено сообщение. В свою очередь, клиентское приложение не может узнать статус отправленного сообщения, то есть получено оно хоть каким-то сервером или нет. В остальном это неплохая замена сокетам, требующим сетевое подключение, или пайпам, которые могут быть открыты только двумя процессами и не поддерживают широковещательные рассылки.
Для создания канала используется функция CreateMailslot, которая в качестве одного из параметров принимает имя канала. Имя канала для серверного приложения должно иметь вид \\.\mailslot\имя_канала, при этом имя должно быть уникальным для приложения, но одинаковым в пределах клиента и сервера. Создавать канал должна серверная часть приложения. Она же определяет максимальный размер передаваемых сообщений и время ожидания. В случае необходимости этот параметр можно менять при помощи функции SetMailslotInfo.
Получив хэндл канала, сервер будет читать из него присланные сообщения. Обработчик выполняется в цикле по таймеру или же в отдельном потоке с задержкой между итерациями. Каждый шаг цикла начинается с получения состояния канала, это делается при помощи функции GetMailslotInfo, она возвращает количество сообщений в очереди на момент запроса и размер сообщения, которое будет получено первым. Если сообщений в очереди нет, то после выполнения функции параметр lpMessageCount будет равен нулю, а параметр lpNextSize примет значение MAILSLOT_NO_MESSAGE. Полученные сообщения читаются из канала функцией ReadFile, будто из обычного текстового файла.
Таким образом, простейшее серверное приложение для работы с Mailslot будет иметь следующий вид:
Code (Assembler) : Убрать нумерацию
- proc DialogProc hwnddlg,msg,wparam,lparam
- push ebx esi edi
- cmp [msg],WM_INITDIALOG
- je .wminitdialog
- cmp [msg],WM_COMMAND
- je .wmcommand
- cmp [msg],WM_CLOSE
- je .wmdone
- cmp [msg],WM_TIMER
- je .wmtimer
- xor eax,eax
- jmp .finish
- .wminitdialog:
- ; Создать канал получения данных
- invoke CreateMailslot,mailslot,0,\
- MAILSLOT_WAIT_FOREVER, NULL
- cmp eax,INVALID_HANDLE_VALUE
- je .wmclose
- mov [hMailSlot],eax
- ; Установить таймер для обработки канала
- invoke SetTimer,[hwnddlg],1,100,NULL
- jmp .processed
- .wmcommand:
- cmp [wparam],BN_CLICKED shl 16 + IDCANCEL
- je .wmdone
- jmp .processed
- .wmtimer:
- ; Получить состояние канала
- invoke GetMailslotInfo,[hMailSlot],NULL,dSize,dNum,NULL
- cmp [dNum],0
- je .processed
- ; Получить данные из канала
- invoke ReadFile,[hMailSlot],buff,[dSize],tmp,NULL
- ; buff -> текст сообщения
- jmp .processed
- .wmdone:
- ; Удалить таймер и закрыть канал
- invoke KillTimer,[hwnddlg],1
- invoke CloseHandle,[hMailSlot]
- .wmclose:
- invoke EndDialog,[hwnddlg],0
- .processed:
- mov eax,1
- .finish:
- pop edi esi ebx
- ret
- endp
Собираем все вместе и получаем заготовку клиентского приложения.
Code (Assembler) : Убрать нумерацию
- proc DialogProc hwnddlg,msg,wparam,lparam
- push ebx esi edi
- cmp [msg],WM_INITDIALOG
- je .wminitdialog
- cmp [msg],WM_COMMAND
- je .wmcommand
- cmp [msg],WM_CLOSE
- je .wmdone
- xor eax,eax
- jmp .finish
- .wminitdialog:
- ; Открыть существующий канал
- invoke CreateFile,mailslot,GENERIC_WRITE,\
- FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL
- cmp eax,INVALID_HANDLE_VALUE
- je .wmclose
- mov [hMailslot],eax
- jmp .processed
- .wmcommand:
- cmp [wparam],BN_CLICKED shl 16 + IDCANCEL
- je .wmdone
- cmp [wparam],BN_CLICKED shl 16 + ID_SEND
- je .wmsend
- jmp .processed
- .wmsend:
- ; Отправить сообщение в канал
- invoke WriteFile,[hMailslot],szMessage,[dSize],tmp,NULL
- jmp .processed
- .wmdone:
- ; Закрыть канал
- invoke CloseHandle,[hMailslot]
- .wmclose:
- invoke EndDialog,[hwnddlg],0
- .processed:
- mov eax,1
- .finish:
- pop edi esi ebx
- ret
- endp
Просмотров: 467 | Комментариев: 0
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет
Добавить комментарий
Заполните форму для добавления комментария