2009-12-08 23 views
13

Comencé a escribir un control ActiveX que hace uso de sockets.¿Es posible saber si WSAStartup ha sido llamado en un proceso?

Las aplicaciones que usan este control también pueden o no usar sockets. ¿Mi control puede indicar si se ha llamado a WSAStartup?

Si no, llámalo. Una pequeña prueba revela que llamar a WSAStartup varias veces es tolerado. ¿Pero qué ocurre si se solicita una versión diferente de winsock? ¿Esto romperá otras partes de la aplicación?

Respuesta

26

Sí es posible.

Y así es como se hace.

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. 
    // ...   
} 

Pero no es realmente necesario hacer esto. Es bastante seguro llamar a WSAStartup en cualquier momento. También es seguro finalizar cada llamada exitosa a WSAStartup() con una llamada correspondiente a WSACleanup().

p. Ej.

// 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 
+6

No olvides llamar 'closesocket()' si 'socket()' tiene éxito en 'WinsockInitialized()', de lo contrario, tienes una fuga. –

+1

¡buen punto! arregló eso. – Matt

+0

No es seguro llamar a WSAStartup en cualquier momento. Desde MSDN: "La función WSAStartup normalmente lleva a que se carguen archivos DLL auxiliares específicos del protocolo. Como resultado, la función WSAStartup no se debe invocar desde la función DllMain en una DLL de aplicación. Esto puede provocar interbloqueos" – czz

2
  • No, no es posible saber si WSAStartup() ya se ha llamado.

  • Sí, WSAStartup() se puede invocar varias veces en un único proceso, siempre que la versión solicitada sea compatible con WinSock DLL. Las llamadas a WSAStartup() y WSACleanup() deben estar balanceadas.

  • La inicialización de WinSock es un proceso negociado; usted es responsable de validar la información que WSAStartup() devuelve para asegurarse de que cumpla con los requisitos de su aplicación.

  • Las tomas existentes no se ven afectadas por las siguientes llamadas WSAStartup().

  • Se permite el uso de varios sockets con diferentes versiones de WinSock.

Consulte the WSAStartup() documentation para obtener más información.

+0

Además de esto, he descubierto que mientras el número de llamadas WSACleanup coincide con el número de llamadas exitosas WSAStartup luego llamar WSACleanup no afectará a otras llamadas de socket. Siempre que, por supuesto, no llame a WSACleanup muchas veces. – Matt

Cuestiones relacionadas