【问题标题】:Is it possible to tell if WSAStartup has been called in a process?是否可以判断 WSAStartup 是否已在进程中调用?
【发布时间】:2020-05-18 05:09:38
【问题描述】:

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

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

如果没有,请调用它。一个小测试表明多次调用 WSAStartup 是可以接受的。 但是如果请求不同的 winsock 版本会发生什么?这会破坏应用程序的其他部分吗?

【问题讨论】:

    标签: windows winsock2 windows-socket-api wsastartup


    【解决方案1】:

    是的,这是可能的。

    这就是它的完成方式。

    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 是非常安全的。使用对 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
    

    【讨论】:

    • 在任何时候调用 WSAStartup 都是不安全的。来自 MSDN:“WSAStartup 函数通常会导致加载特定于协议的帮助程序 DLL。因此,不应从应用程序 DLL 中的 DllMain 函数调用 WSAStartup 函数。这可能会导致死锁”
    • WinsockInitialized() 如果socket()WSANOTINITIALISED 以外的任何错误代码而失败,则返回true 而不是false(MSDN 显示socket() 可能失败的13 个可能的错误代码)。 WSAGetLastError() 检查无论如何都是多余的,因为 socket() 要么成功要么失败,检查错误代码不会改变结果。 bool WinsockInitialized() { SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET) return false; closesocket(s); return true; }
    【解决方案2】:
    • 不,无法判断 WSAStartup() 是否已被调用。

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

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

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

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

    更多信息请参见the WSAStartup() documentation

    【讨论】:

    • 除此之外,我发现只要 WSACleanup 调用的数量与成功的 WSAStartup 调用的数量相匹配,那么调用 WSACleanup 就不会影响其他套接字调用。当然,前提是您不会多次调用 WSACleanup。
    猜你喜欢
    • 2011-07-27
    • 2011-06-26
    • 1970-01-01
    • 2014-07-04
    • 1970-01-01
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多