我正在使用嵌入了资源管理器的win 7替换,以便系统直接启动到我的应用程序。
我发现,当我的应用程序启动时,网络堆栈尚未就绪,我无法绑定到任何网络地址。不幸的是,它不是一个简单的网络要求,有很多不同的螺纹部件在不同的时间开始。插件系统可以启动网络接口,telnet接口,UDP发现广播线程等。
当我的应用程序开始检测网络堆栈是否启动并运行时,有一种简单的方法吗?
应用程序主要是使用Indy组件的Delphi(但插件是使用asio的c ++)。
此刻的作弊解决方案是在" Application.Initialize"之前进行4秒的睡眠。它总是正确启动。如果我在" Application.Initialize"之后进入睡眠状态。所以这告诉我,有些组件正在初始化例程中执行WSAStartup,这就是破坏事物。
答案 0 :(得分:2)
将等待的电话转到您某个设备的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.
答案 1 :(得分:1)
问题原来不是网络堆栈,而是特定接口。当各种网络组件启动时,他们尝试绑定到可用端口。因为应用程序启动得如此之快,物理端口不可用,并且没有任何限制。
解决方案是编写一个原始winsock例程来获取可用端口列表,并等待端口计数> 1(在需要应用程序的最开始时需要考虑环回)。
作为参考,这是我用来获取接口列表的API:
WSAIoctl(fSocket, SIO_GET_INTERFACE_LIST, Nil, 0, @InterfaceList, sizeof(InterfaceList), @BytesRet, Nil, Nil);