是否可以判断是否在进程中调用了WSAStartup?

Mat*_*att 15 windows winsock2 windows-socket-api wsastartup

我已经开始编写一个使用套接字的ActiveX控件.

使用此控件的应用程序可能也可能不使用套接字.我的控件是否可以判断是否已调用WSAStartup?

如果没有,请拨打电话.一个小小的测试表明,多次调用WSAStartup是很容易的.但是如果要求使用不同的winsock版本会发生什么?这会破坏应用程序的其他部分吗?

Mat*_*att 29

对的,这是可能的.

以下是它的完成方式.

bool WinsockInitialized()
{
    SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == INVALID_SOCKET && WSAGetLastError() == WSANOTINITIALISED){
        return false;
    }

    closesocket(s)
    return true;
}

int main()
{
    //...
    if ( !WinsockInitialized() )
       // Init winsock here...

    // Carry on as normal.
    // ...         
}
Run Code Online (Sandbox Code Playgroud)

但这并不是必须的.随时调用WSAStartup非常安全.使用与WSACleanup()的匹配调用结束对WSAStartup()的每次成功调用也是安全的.

例如

// 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
Run Code Online (Sandbox Code Playgroud)

  • 如果 `socket()` 因除 `WSANOTINIITIALISED` 以外的任何错误代码而失败,`WinsockInitialized()` 将返回 true 而不是 false(MSDN 显示了 `socket()` 可能会失败的 13 种可能的错误代码)。“WSAGetLastError()”检查无论如何都是多余的,因为“socket()”要么成功要么失败,检查错误代码不会改变结果。`bool WinsockInitialized() { SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET) 返回 false;关闭套接字;返回真;}` (2认同)

Rem*_*eau 5

  • 不,无法判断是否WSAStartup()已经被调用。

  • WSAStartup()可以,只要 WinSock DLL 支持请求的版本,就可以在单个进程中多次调用。调用WSAStartup()WSACleanup()必须平衡。

  • WinSock 初始化是一个协商的过程;您有责任验证WSAStartup()返回的信息以确保它满足您的应用程序的要求。

  • 现有套接字不受后续WSAStartup()调用的影响。

  • 允许使用不同 WinSock 版本的多个套接字。

请参阅WSAStartup()文档以获取更多信息。