Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Реализация mDNS-запросов в Delphi: поиск устройств в сети с помощью Indy

Delphi , Интернет и Сети , TCP/IP

 

В этой статье мы рассмотрим, как реализовать поиск устройств в локальной сети с использованием протокола mDNS (Multicast DNS) в среде Delphi. Этот протокол, также известный как Zeroconf или Bonjour, позволяет устройствам находить друг друга в локальной сети без необходимости настройки DNS-сервера.

Что такое mDNS?

mDNS - это протокол, который использует multicast-рассылку на порт 5353 для разрешения имен устройств в локальных сетях. Он широко используется в IoT-устройствах, принтерах, PLC (программируемых логических контроллерах) и других сетевых устройствах.

Реализация mDNS в Delphi с использованием Indy

Для реализации mDNS-запроса мы будем использовать компоненты из библиотеки Indy (Internet Direct):

  • TIdIPMCastServer - для отправки mDNS-запроса
  • TIdUDPServer - для приема ответов от устройств

Основной код для отправки mDNS-запроса

procedure TfrmMain.mnuMulticastClick(Sender: TObject);
var
  query: TIdBytes = (
    $00, $00, // Transaction ID
    $00, $00, // Standard query
    $00, $01, // Question count
    $00, $00, // Answer RRs count
    $00, $00, // Authority RRs count
    $00, $00, // Additional RRs count
    // Query string for _services._dns-sd._udp.local
    $09, $5F, $73, $65, $72, $76, $69, $63, $65, $73, // _services
    $07, $5F, $64, $6E, $73, $2D, $73, $64,           // _dns-sd
    $04, $5F, $75, $64, $70,                          // _udp
    $05, $6C, $6F, $63, $61, $6C,                     // local
    $00, // Null terminator
    $00, $0C, // Type PTR
    $00, $01  // Class IN
  );
begin
  // Настройка Multicast сервера
  IdIPMCastServer.MulticastGroup := Id_IPMC_mDNS;
  IdIPMCastServer.BoundIP := '192.168.1.100'; // IP вашего сетевого адаптера
  IdIPMCastServer.BoundPort := 49152; // Порт для ответов
  IdIPMCastServer.Port := 5353; // Стандартный порт mDNS

  // Настройка UDP сервера
  IdUDPServer.Bindings.Add;
  IdUDPServer.Bindings[0].IP := '192.168.1.100';
  IdUDPServer.Bindings[0].Port := 49152;

  // Отправка запроса
  IdIPMCastServer.Active := True;
  IdIPMCastServer.Send(query);

  // Деактивация Multicast сервера и активация UDP сервера
  IdIPMCastServer.Active := False;
  tmUDPdeactivate.Interval := IdIPMCastServer.TimeToLive * 1000;
  tmUDPdeactivate.Enabled := True;
  IdUDPServer.Active := True;
end;

Обработка ответов от устройств

procedure TfrmMain.IdUDPServerUDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
  // Добавляем найденное устройство в StringGrid
  sgMachines.InsertRowWithValues(sgMachines.RowCount, 
    [IPAddrToName(ABinding.PeerIP), ABinding.PeerIP]);
end;

Альтернативные подходы

Как отметил Remy Lebeau, можно использовать один компонент TIdUDPServer для обеих задач - отправки запроса и приема ответов:

procedure TfrmMain.SendmDNSQuery;
var
  query: TIdBytes;
  Binding: TIdSocketHandle;
begin
  // Инициализация запроса (как в предыдущем примере)

  // Настройка UDP сервера
  IdUDPServer.Bindings.Add;
  Binding := IdUDPServer.Bindings[0];
  Binding.IP := '192.168.1.100';
  Binding.Port := 49152;
  Binding.ReuseSocket := rsTrue;

  // Отправка запроса на multicast-адрес
  IdUDPServer.Active := True;
  Binding.SendTo(Id_IPMC_mDNS, 5353, query);

  // Ответы будут приходить в событии OnUDPRead
end;

Парсинг mDNS-ответов

Для более сложного анализа ответов можно использовать структуры данных:

type
  TmDNSQuestion = packed record
    Query: array of Byte; // Длина строки + данные (не null-terminated)
    QueryType: Word;
    QueryClass: Word;
  end;

  TmDNSAnswer = packed record
    AnswerName: Word;
    AnswerType: Word;
    AnswerClass: Word;
    CacheFlush: Word;
    TimeToLive: LongWord;
    DataLength: Word;
    Data: array of Byte;
  end;

  TmDNSResponse = packed record
    TransactionID: Word;
    Flags: Word;
    Questions: Word;
    AnswerRRs: Word;
    AuthorityRRs: Word;
    AdditionalRRs: Word;
    QuestionsData: array of TmDNSQuestion;
    AnswersData: array of TmDNSAnswer;
  end;

Готовые решения

Для тех, кто не хочет реализовывать mDNS с нуля, существуют готовые библиотеки:

  1. mdns4Delphi - обновленная версия библиотеки для работы с mDNS в современных версиях Delphi и FPC.
  2. Использование Bonjour SDK от Apple (доступно для Windows).

Заключение

Реализация mDNS-запросов в Delphi требует понимания сетевых протоколов и работы с multicast-трафиком. Представленные примеры демонстрируют базовый функционал для поиска устройств в локальной сети. Для более сложных сценариев рекомендуется использовать готовые библиотеки или углубленно изучить спецификацию протокола mDNS.

Приведенный код может быть адаптирован для поиска конкретных типов устройств (например, PLC или принтеров) путем изменения строки запроса и анализа ответов.

Создано по материалам из источника по ссылке.

Реализация поиска устройств в локальной сети с использованием протокола mDNS в Delphi через библиотеку Indy.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: TCP/IP ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-07-19 00:15:40/0.0034458637237549/0