Как реализовать обмен информацией между Вашими приложениями в сети? ОС Windows предлагает несколько технологий. Эта статья опишет один очень простой и надежный способ для Win9x/NT - MailSlots.
The CreateMailslot function creates a mailslot with the specified name and returns a handle that a mailslot server can use to perform operations on the mailslot. The mailslot is local to the computer that creates it. An error occurs if a mailslot with the specified name already exists.
Обмен текстовыми данными в локальной сети очень прост. Для этого необходимы функции:
CreateMailslot
создание почтового канала;
GetMailslotInfo
определение наличия сообщения в канале;
ReadFile
чтение сообщения из канала, как из файла;
WriteFile
запись сообщения в канал, как в файл;
Функции работы с почтовыми каналами присутствуют как в Windows 9x, так и в Windows NT.
Рассмотрим создание почтового канала (сервер).
//... создание канала с именем MailSlotName - по этому имени к нему// будут обращаться клиенты
h := CreateMailSlot(PChar('\\.\mailslot\' + MailSlotName),
0, MAILSLOT_WAIT_FOREVER,nil);
if h = INVALID_HANDLE_VALUE thenbeginraise Exception.Create('MailSlotServer: Ошибка создания канала !');
Отправка сообщений по почтовомуо каналу (клиенты).
ifnot GetMailSlotInfo(h,nil,DWORD(MsgNext),@MsgNumber,nil) thenbeginraise Exception.Create('TglMailSlotServer: Ошибка сбора информации!');
end;
if MsgNext <> MAILSLOT_NO_MESSAGE thenbegin
beep;
// чтение сообщения из канала и добавление в текст протоколаif ReadFile(h,str,200,DWORD(read),nil) then
MessageText := str
elseraise Exception.Create('TglMailSlotServer: Ошибка чтения сообщения !');
end;
Все очень просто. Теперь для удобства использования создадим два компонента - клиент и сервер
{
Globus Delphi VCL Extensions Library
' GLOBUS LIB '
Freeware
Copyright (c) 2000 Chudin A.V, FidoNet: 1246.1
gl3DCol Unit 05.2000 components TglMailSlotServer, TglMailSlotClient
}unit glMSlots;
interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, extctrls;
type
TOnNewMessage = procedure (Sender: TObject; MessageText: string) ofobject;
TglMailSlotServer = class(TComponent)
private
FMailSlotName, FLastMessage: string;
FOnNewMessage: TOnNewMessage;
Timer: TTimer; //...таймер для прослушивания канала
h : THandle;
str : string[250];
MsgNumber,MsgNext,read : DWORD;
publicconstructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Open; //...создание канала
procedure Close; //...закрытие канала
protectedprocedure Loaded; override;
procedure OnTimer(Sender: TObject);
publishedproperty MailSlotName: stringread FMailSlotName write FMailSlotName;
//...событие получения сообщенияproperty OnNewMessage: TOnNewMessage read FOnNewMessage write FOnNewMessage;
end;
TglMailSlotClient = class(TComponent)
private
FMailSlotName, FServerName, FLastMessage: string;
publicconstructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function Send(str: string):boolean; //...отправка сообщенияprotectedprocedure Loaded; override;
procedure ErrorCatch(Sender : TObject; Exc : Exception);
publishedproperty ServerName: stringread FServerName write FServerName;
property MailSlotName: stringread FMailSlotName write FMailSlotName;
end;
procedureregister;
implementationprocedureregister;
begin
RegisterComponents('Gl Components', [TglMailSlotServer, TglMailSlotClient]);
end;
constructor TglMailSlotServer.Create(AOwner: TComponent);
begininherited;
FEnabled := true;
FMailSlotName := 'MailSlot';
Timer := TTimer.Create(nil);
Timer.Enabled := false;
Timer.OnTimer := OnTimer;
end;
destructor TglMailSlotServer.Destroy;
begin
Timer.Free;
// закрытие канала
Close;
inherited;
end;
procedure TglMailSlotServer.Loaded;
begininherited;
Open;
end;
procedure TglMailSlotServer.Open;
begin// создание канала с именем MailSlotName - по этому имени к нему// будут обращаться клиенты
h := CreateMailSlot(PChar('\\.\mailslot\' + MailSlotName),
0, MAILSLOT_WAIT_FOREVER,nil);
//h:=CreateMailSlot('\\.\mailslot\MailSlot', 0, MAILSLOT_WAIT_FOREVER,nil);if h = INVALID_HANDLE_VALUE thenraise Exception.Create('TglMailSlotServer: Ошибка создания канала !');
Timer.Enabled := true;
end;
procedure TglMailSlotServer.Close;
beginif h <> 0 then
CloseHandle(h);
h := 0;
end;
procedure TglMailSlotServer.OnTimer(Sender: TObject);
var
MessageText: string;
begin
MessageText := '';
// определение наличия сообщения в каналеifnot GetMailSlotInfo(h,nil,DWORD(MsgNext),@MsgNumber,nil) thenraise Exception.Create('TglMailSlotServer: Ошибка сбора информации!');
if MsgNext <> MAILSLOT_NO_MESSAGE thenbegin
beep;
// чтение сообщения из канала и добавление в текст протоколаif ReadFile(h,str,200,DWORD(read),nil) then
MessageText := str
elseraise Exception.Create('TglMailSlotServer: Ошибка чтения сообщения !');
end;
if (MessageText<>'')and Assigned(OnNewMessage) then
OnNewMessage(self, MessageText);
FLastMessage := MessageText;
end;
constructor TglMailSlotClient.Create(AOwner: TComponent);
begininherited;
FMailSlotName := 'MailSlot';
FServerName := '';
end;
destructor TglMailSlotClient.Destroy;
begininherited;
end;
procedure TglMailSlotClient.Loaded;
begininherited;
Application.OnException := ErrorCatch;
end;
procedure TglMailSlotClient.ErrorCatch(Sender : TObject; Exc : Exception);
var
UserName: array[0..99] of char;
i: integer;
begin// получение имени пользователя
i:=SizeOf(UserName);
GetUserName(UserName,DWORD(i));
Send('/'+UserName+'/'+FormatDateTime ('hh:mm',Time)+'/'+Exc.message);
// вывод сообщения об ошибке пользователю
Application.ShowException(Exc);
end;
function TglMailSlotClient.Send(str: string):boolean;
var
strMess: string[250];
UserName: array[0..99] of char;
h: THandle;
i: integer;
begin// открытие канала : MyServer - имя сервера// (\\.\\mailslot\xxx - монитор работает на этом же ПК)// xxx - имя каналаif FServerName = '' then
FServerName := '.\';
h:=CreateFile( PChar('\\' + FServerName + '\mailslot\' + FMailSlotName),
GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
if h <> INVALID_HANDLE_VALUE thenbegin
strMess := str;
// передача текста ошибки (запись в канал и закрытие канала)
WriteFile(h, strMess, Length(strMess) + 1, DWORD(i), nil);
CloseHandle(h);
end;
Result := h <> INVALID_HANDLE_VALUE;
end;
end.
Компонент TglMailSlotServer создает почтовый канал с именем MailSlotName и принимает входящие сообщения. Компонент TglMailSlotClient отправляет сообщения в канал с именем MailSlotName на машине ServerName.
Эти компонеты входят в состав библиотеки GlobusLib, распространяемой с исходными текстами.
Статья описывает простой и надежный способ обмена информацией между программами в сети с помощью mailslots на Windows 9x/NT.
Mailslots - это технология, предоставляемая операционной системой, которая позволяет множеству программ общаться друг с другом через общую почтовую ящик. Программа может создать mailslot, отправлять сообщения в него и получать сообщения из него.
Статья предлагает пример использования mailslots в Delphi. Она определяет два компонента: TglMailSlotServer и TglMailSlotClient. Первый создает mailslot с указанным именем и слушает входящие сообщения, а второй отправляет сообщения в mailslot на удаленном компьютере.
Вот разбивка кода:
TglMailSlotServer
Создает mailslot с указанным именем с помощью функции CreateMailSlot.
Открывает mailslot и настраивает таймер для прослушивания входящих сообщений.
В событии OnTimer проверяет, есть ли новые сообщения в mailslot с помощью функции GetMailSlotInfo. Если есть сообщение, читает сообщение из mailslot с помощью функции ReadFile и вызывает обработчик события OnNewMessage для обработки сообщения.
Предоставляет свойства для настройки имени mail slot и включения/отключения сервера.
TglMailSlotClient
Создает файловый handle для подключения к mailslot удаленного компьютера с помощью функции CreateFile.
Отправляет сообщения в mailslot, записывая их в файловый handle с помощью функции WriteFile.
Предоставляет свойства для настройки имени mail slot и имени сервера.
Код относительно прост и легко понятен. Однако есть несколько потенциальных проблем:
Обработка ошибок: код не обеспечивает обширную обработку ошибок, что может привести к краху или неожиданному поведению при возникновении ошибки при общении с mailslot.
Безопасность: mailslots - это локальная технология, но они могут быть уязвимы для безопасности, если не используются правильно. Например, если зловредная программа получит доступ к mailslot, она может отправлять спам-сообщения или вставлять вредоносное программное обеспечение в другие программы, использующие тот же mailslot.
Производительность: производительность mailslots может ухудшаться с течением времени, если количество отправляемых и получаемых сообщений увеличивается.
В целом, этот код предоставляет базовое реализацию mailslots в Delphi и может быть использован как стартовая точка для более сложных приложений. Однако важно учитывать ограничения и потенциальные проблемы, упомянутые выше, при проектировании вашего приложения.
Обмен информацией между программами в сети по почтовым каналам: реализация обмена текстовыми данными на платформе Windows 9x/NT с помощью технологии MailSlots.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.