2009-12-08 23 views
13

Zacząłem pisać formant ActiveX, który korzysta z gniazd.Czy można sprawdzić, czy WSAStartup został wywołany w procesie?

Aplikacje korzystające z tej kontroli mogą, ale nie muszą również używać gniazd. Czy moja kontrola może stwierdzić, czy wywołano funkcję WSAStartup?

Jeśli nie, zadzwoń. Mały test pokazuje, że wielokrotne wywoływanie WSAStartup jest tollerowane. Ale co się stanie, jeśli zażąda się innej wersji serwera winsock? Czy złamie to inne części aplikacji?

Odpowiedz

26

Tak, jest to możliwe.

I oto jak to się robi.

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

Ale nie jest to naprawdę konieczne. W każdej chwili można bezpiecznie wywołać WSAStartup. Bezpieczne jest także zakończenie każdego udanego połączenia z WSAStartup() z pasującym połączeniem do WSACleanup().

np.

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

Nie zapomnij wywołać 'closesocket()' jeśli 'socket()' zakończyło się pomyślnie w 'WinsockInitialized()', w przeciwnym razie wystąpi przeciek. –

+1

dobry punkt! naprawiono to. – Matt

+0

Wywołanie WSAStartup w dowolnym momencie NIE jest bezpieczne. Z MSDN: "Funkcja WSAStartup zazwyczaj prowadzi do ładowania zależnych od protokołu bibliotek DLL pomocniczych, w wyniku czego funkcja WSAStartup nie powinna być wywoływana z funkcji DllMain w bibliotece DLL aplikacji, co może potencjalnie powodować zakleszczenia" – czz

2
  • Nie, to nie jest możliwe, aby stwierdzić, czy WSAStartup() została już wywołana.

  • Tak, WSAStartup() można wywołać wiele razy w jednym procesie, o ile żądana wersja jest obsługiwana przez bibliotekę DLL WinSock. Połączenia z numerami WSAStartup() i WSACleanup() muszą być zrównoważone.

  • Inicjalizacja WinSock jest negocjowanym procesem; jesteś odpowiedzialny za sprawdzanie informacji, które zwraca WSAStartup(), aby upewnić się, że spełnia wymagania Twojej aplikacji.

  • Na istniejące gniazda nie mają wpływu kolejne wywołania WSAStartup().

  • Dozwolone jest używanie wielu gniazd przy użyciu różnych wersji WinSock.

Aby uzyskać więcej informacji, zobacz the WSAStartup() documentation.

+0

Poza tym odkryłem, że tak długo, jak liczba połączeń WSACleanup dopasować liczbę udanych połączeń WSAStartup następnie wywołanie WSACleanup nie będzie miało wpływu na inne połączenia gniazda. Oczywiście pod warunkiem, że nie powołasz WSACleanup zbyt wiele razy. – Matt

Powiązane problemy