2009-12-08 12 views
13

Ho iniziato a scrivere un controllo ActiveX che fa uso di socket.È possibile stabilire se WSAStartup è stato chiamato in un processo?

Le applicazioni che utilizzano questo controllo possono utilizzare o meno anche le prese. È possibile per il mio controllo dire se WSAStartup è stato chiamato?

In caso contrario, chiamarlo. Un piccolo test rivela che la chiamata a WSAStartup più volte è tollerata. Ma cosa succede se viene richiesta una versione di winsock diversa? questo interromperà altre parti dell'applicazione?

risposta

26

Sì, è possibile.

Ed ecco come è fatto.

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

ma non è proprio necessario fare questo. È abbastanza sicuro chiamare WSAStartup in qualsiasi momento. È anche sicuro terminare ogni chiamata riuscita a WSAStartup() con una chiamata corrispondente a WSACleanup().

ad es.

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

Non dimenticare di chiamare 'closesocket()' se 'socket()' ha successo in 'WinsockInitialized()', altrimenti c'è una perdita. –

+1

buon punto! risolto quello. – Matt

+0

Non è sicuro chiamare WSAStartup in qualsiasi momento. Da MSDN: "La funzione WSAStartup in genere porta a DLL helper specifiche del protocollo che vengono caricate. Di conseguenza, la funzione WSAStartup non deve essere chiamata dalla funzione DllMain in una DLL dell'applicazione. Ciò può potenzialmente causare deadlock" – czz

2
  • No, non è possibile sapere se WSAStartup() è già stato chiamato.

  • Sì, WSAStartup() può essere chiamato più volte in un singolo processo, purché la versione richiesta sia supportata dalla DLL di WinSock. Le chiamate a WSAStartup() e WSACleanup() devono essere bilanciate.

  • L'inizializzazione di WinSock è un processo negoziato; sei responsabile della convalida delle informazioni che WSAStartup() restituisce per assicurarsi che soddisfi i requisiti della tua app.

  • Le prese esistenti non sono interessate dalle successive chiamate WSAStartup().

  • Sono consentite prese multiple che utilizzano versioni di WinSock diverse.

Vedere the WSAStartup() documentation per ulteriori informazioni.

+0

In aggiunta a questo, ho trovato che fino a quando il numero di chiamate WSACleanup corrisponde al numero di chiamate WSAStartup successo quindi chiamando WSACleanup non influenzerà altre chiamate di socket. Ovviamente, non si chiama WSACleanup troppe volte. – Matt