我已经开始编写一个利用 sockets 的 ActiveX 控件。
使用此控件的应用程序可能会或可能不会同时使用 sockets。 我的控件是否能够判断 WSAStartup 是否已经被调用?
如果不能,就调用它。通过一个简单的测试可以发现,多次调用 WSAStartup 是被允许的。 但是,如果请求不同的 winsock 版本,会不会破坏应用程序的其他部分呢?
我已经开始编写一个利用 sockets 的 ActiveX 控件。
使用此控件的应用程序可能会或可能不会同时使用 sockets。 我的控件是否能够判断 WSAStartup 是否已经被调用?
如果不能,就调用它。通过一个简单的测试可以发现,多次调用 WSAStartup 是被允许的。 但是,如果请求不同的 winsock 版本,会不会破坏应用程序的其他部分呢?
是的,这是可能的。
下面是具体实现方法。
bool WinsockInitialized()
{
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET){
return false;
}
closesocket(s);
return true;
}
int main()
{
//...
if ( !WinsockInitialized() )
// Init winsock here...
// Carry on as normal.
// ...
}
不过这并不是必须的。在任何时候调用WSAStartup都是非常安全的。同时,在每次成功调用WSAStartup()后,使用匹配的调用WSACleanup()也是安全的。
例如:
// socket calls here would be an error, not initialized
WSAStartup(...)
// socket calls here OK
WSAStartup(...)
// more socket calls OK
WSACleanup()
// socket calls OK
WSACleanup()
// more socket calls error, not initialized
不,无法判断WSAStartup()
是否已经被调用。
是的,在单个进程中可以多次调用WSAStartup()
,只要请求的版本由WinSock DLL支持。调用WSAStartup()
和WSACleanup()
必须平衡。
WinSock初始化是一个协商过程;您负责验证WSAStartup()
返回的信息,以确保它满足您应用程序的要求。
现有套接字不会受到后续WSAStartup()
调用的影响。
允许使用不同的WinSock版本的多个套接字。
更多信息请参见WSAStartup()
文档。
socket()
函数失败并返回除WSANOTINITIALISED
之外的任何错误代码,WinsockInitialized()
函数仍然会返回true,这是不正确的。根据MSDN文档,socket()
函数有13个可能的错误代码。无论如何,进行WSAGetLastError()
检查是多余的,因为socket()
函数要么成功,要么失败,检查错误代码不会改变结果。下面是翻译后的代码:bool WinsockInitialized() { SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET) { if (WSAGetLastError() != WSANOTINITIALISED) { return false; } } closesocket(s); return true; }
- Remy Lebeau