Обнаружение загрузки сетевого стека в Win 7

Я использую встроенную win 7 с замененным проводником, чтобы система загружалась прямо в мое приложение.

Я обнаружил, что к тому моменту, когда мое приложение запускается, сетевой стек не готов, и мне не удается привязаться к каким-либо сетевым адресам. К сожалению, это не простые сетевые требования с множеством разных резьбовых частей, начинающихся в разное время. Существует подключаемая система, которая может запускать сетевые интерфейсы, интерфейс telnet, широковещательный поток UDP-обнаружения и т. Д.

Есть ли простой способ, когда мое приложение начинает обнаруживать, работает ли сетевой стек?

Приложение в основном Delphi, использующее компоненты Indy (но плагины C++, использующие asio).

В настоящее время чит-решение состоит в том, чтобы перед сном "Application.Initialize" поставить 4-секундный сон, и он всегда запускается правильно. Если я помещаю сон после "Application.Initialize", это говорит мне о том, что есть компоненты, которые выполняют WSAStartup в своей процедуре инициализации, и это то, что ломает вещи.

2 ответа

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

Решение состояло в том, чтобы написать сырую подпрограмму winsock, чтобы получить список доступных портов и подождать, пока число портов> 1 (необходимо учитывать обратную связь) в самом начале приложения.

Для справки это API, который я использовал для получения списка интерфейсов:

WSAIoctl(fSocket, SIO_GET_INTERFACE_LIST, Nil, 0, @InterfaceList, sizeof(InterfaceList), @BytesRet, Nil, Nil);

Переведите ожидающий вызов в WSAStartup в initialization раздел одного из вашего устройства, пока сеть не будет успешно инициализирована.

unit NetworkWaitUnit;

interface

implementation

uses
  Windows,
  yourWinSockUnit; 

var
  WsaDataOnce: TWSADATA;

const
  WinsockLevel = $0202;

initialization
  while not WSAStartup(WinsockLevel, WsaDataOnce) do
    sleep(100);
end.

Затем убедитесь, что этот блок указан первым в .dpr uses список объектов. В результате он будет вызываться раньше всех других модулей, и ваша программа должна работать как положено.

Нечто похожее на это:

program MyServer;

uses
  NetworkWaitUnit, // should be listed first to be called first
  SysUtils,
  ...


end.
Другие вопросы по тегам