Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Авторские статьи (https://forum.antichat.xyz/forumdisplay.php?f=31)
-   -   Бесформенное использование INDY на примере Id http ProxyServer (https://forum.antichat.xyz/showthread.php?t=38342)

begin_end 19.04.2007 18:55

Бесформенное использование INDY на примере Id http ProxyServer
 
Цели данной, совсем небольшой, статьи:

рассказать о способе использования компонентов INDY, не применяя VCL-формы Дельфи (зачем это нужно: это делает ваши приложения оптимальнее, сильно сокращает размер);
показать возможность быстрого и простого создания прокси-сервера.

Рассчитано на программистов на Дельфи, работающих с INDY-компонентами.

Начну с того, что кратко скажу об обычном применении компонентов INDY на примере idHTTPProxyServer.
Внимание: он отсутствует в INDY версии 9 (которая с Дельфи 7), необходимо обновить до 10 версии.

Создаем пустую форму. На вкладке компонентов ищем Indy Servers ит там будет idHTTPProxyServer. Кладём его на форму. Далее в параметрах компонента указываем порт, например, 81 и Active=true. Запускаем приложение и мы уже можем соединятся с ним по 81 порту. Прокси сервер готов! Но приложение имеет вес более 500 Кб и не нужную нам форму. Как же быть? А так: сделаем часть приложения, необходимую в качестве основы для INDY-компонента на чистом API. Для этого нам понадобится 6 API-функций: RegisterClass, GetMessage, TranslateMessage, DispatchMessage, DefWindowProc, PostQuitMessage. Также нужно будет создать класс и реализовать приём и обработку сообщений. В uses мы указываем только одно – idHTTPProxyServer. Сам прокси-сервер создаётся всего тремя строчками кода. Используем модуль, вызываем функции и обрабатываем сообщения так:

Код:

program Project1;
//файл ресурсов (иконка и проч.)
{$R *.res}

//используем инди-модуль
uses IdHTTPProxyServer;

const
//title нашего класса
  WND_TITLE  = 'PSrv';
//имя нашего класса
  WND_CLASS  = 'PSrv';
  user32    = 'user32.dll';

//вызываемые API-функции
  function RegisterClass(lpWndClass: Pointer): Cardinal; stdcall; external user32 name 'RegisterClassA';
  function GetMessage(lpMsg: Pointer; hWnd, wMsgFilterMin, wMsgFilterMax: Cardinal): boolean; stdcall; external user32 name 'GetMessageA';
  function TranslateMessage(lpMsg: Pointer): Boolean; stdcall; external user32 name 'TranslateMessage';
  function DispatchMessage(lpMsg: Pointer): Integer; stdcall; external user32 name 'DispatchMessageA'
  function DefWindowProc(hWnd, Msg: Cardinal; wParam, lParam: Integer): Integer; stdcall; external user32 name 'DefWindowProcA';
  procedure PostQuitMessage(nExitCode: Integer); stdcall; external user32 name 'PostQuitMessage';

//обработчик сообщений
function WndProc(hwnd, message: Cardinal; wParam, lParam: Integer): Integer; stdcall;
begin
  if message = $0002 then
  begin
    PostQuitMessage(0);
    Result := 0;
  end else
    Result := DefWindowProc(hwnd, message, wParam, lParam);
end;

А, теперь нужно описать структуры класса wnd и сообщения msg. И собственно вставить сам рабочий код, создающий и запускающий прокси-сервер:

Код:

var
//структура wnd
  wnd : packed record
    style        : Cardinal;
    lpfnWndProc  : Pointer;
    cbClsExtra    : Integer;
    cbWndExtra    : Integer;
    hInstance    : Cardinal;
    hIcon        : Cardinal;
    hCursor      : Cardinal;
    hbrBackground : Cardinal;
    lpszMenuName  : PAnsiChar;
    lpszClassName : PAnsiChar;
  end = (
    lpfnWndProc  : @WndProc;
    hbrBackground : 0;
    lpszClassName : WND_CLASS);


var
//определяем прокси-сервер
  IdHTTPProxyServer1: TIdHTTPProxyServer;
//структура msg
  msg : packed record
    hwnd    : Cardinal;
    message : Cardinal;
    wParam  : Integer;
    lParam  : Integer;
    time    : Cardinal;
    X, Y    : Integer;
  end;

begin
//регистрируем класс wnd
  RegisterClass(@wnd);
//создаём прокси-сервер
  IdHTTPProxyServer1:=TIdHTTPProxyServer.Create;
//указываем порт, по какому он будет доступен
  IdHTTPProxyServer1.DefaultPort:=81;
//запускаем прокси-сервер
  IdHTTPProxyServer1.Active:=true;
//приём сообщений структуры msg и их трансляция
    while GetMessage(@msg, 0, 0, 0) do
  begin
    TranslateMessage(@msg);
    DispatchMessage(@msg);
  end;
end.

Этот исходный код и готовое приложение можно скачать здесь. Приложение, упакованное UPX, весит всего 93,5Кб. В работе испытано, работает надёжно. Описанный метод применим к работе с прочими INDY-компонентами, например с idHTTPServer или idSMTP.

Статья и пример были созданы в образовательных целях, по просьбам интересующихся. В ходе работы использовалась среда Delphi 7, но набор компонентов INDY версии 10. Статью можно дополнять, переопубликовывать с разрешения автора. Предложения и критика ожидаемы и желательны.

Fen-Omen 19.04.2007 19:22

Цитата:

Сообщение от begin end
Цели данной, совсем небольшой, статьи:

это делает ваши приложения оптимальнее, сильно сокращает размер)

Сильно - это насколько в персентах будет?

begin_end 19.04.2007 22:50

Программа с idHTTPProxyServer и формой на VCL занимает размер 195Кб в упакованном виде. Описанная в статье - 93,5Кб. Получается, что на 48% или почти в два раза меньше.


Время: 17:49