Udostępnij za pośrednictwem


Tworzenie gniazda dla klienta

Po zainicjowaniu należy utworzyć wystąpienie obiektu SOCKET dla klienta.

Aby utworzyć gniazdo

  1. Zadeklaruj obiekt addrinfo, który zawiera strukturę sockaddr i zainicjuj jego wartości. W przypadku tej aplikacji rodzina adresów internetowych jest nieokreślona, aby można było zwrócić adres IPv6 lub IPv4. Aplikacja żąda, aby typ gniazda był gniazdem strumienia dla protokołu TCP.

    struct addrinfo *result = NULL,
                    *ptr = NULL,
                    hints;
    
    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family   = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    
  2. Wywołaj funkcję getaddrinfo żądającą adresu IP nazwy serwera przekazanej w wierszu polecenia. Port TCP na serwerze, z którego klient będzie się łączyć, jest zdefiniowany przez DEFAULT_PORT jako 27015 w tym przykładzie. Funkcja getaddrinfo zwraca wartość jako liczbę całkowitą sprawdzaną pod kątem błędów.

    #define DEFAULT_PORT "27015"
    
    // Resolve the server address and port
    iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
    if (iResult != 0) {
        printf("getaddrinfo failed: %d\n", iResult);
        WSACleanup();
        return 1;
    }
    
  3. Utwórz obiekt SOCKET o nazwie ConnectSocket.

    SOCKET ConnectSocket = INVALID_SOCKET;
    
  4. Wywołaj funkcjęgniazdai zwróć jej wartość do zmiennej ConnectSocket. W przypadku tej aplikacji użyj pierwszego adresu IP zwróconego przez wywołanie getaddrinfo , który odpowiada rodzinie adresów, typowi gniazda i protokołowi określonemu w parametrze hints. W tym przykładzie określono gniazdo strumienia TCP z typem gniazda SOCK_STREAM i protokołem IPPROTO_TCP. Rodzina adresów nie została określona (AF_UNSPEC), więc zwrócony adres IP może być adresem IPv6 lub IPv4 serwera.

    Jeśli aplikacja kliencka chce nawiązać połączenie przy użyciu tylko protokołu IPv6 lub IPv4, należy ustawić rodzinę adresów na AF_INET6 dla protokołu IPv6 lub AF_INET dla protokołu IPv4 w wskazówkach parametru.

    // Attempt to connect to the first address returned by
    // the call to getaddrinfo
    ptr=result;
    
    // Create a SOCKET for connecting to server
    ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
        ptr->ai_protocol);
    
  5. Sprawdź błędy, aby upewnić się, że gniazdo jest prawidłowym gniazdem.

    if (ConnectSocket == INVALID_SOCKET) {
        printf("Error at socket(): %ld\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        return 1;
    }
    

Parametry przekazywane do gniazda funkcji można zmienić dla różnych implementacji.

Wykrywanie błędów jest kluczową częścią pomyślnego kodu sieciowego. Jeśli wywołanie gniazda za pomocą zakończy się niepowodzeniem, zostanie zwrócony INVALID_SOCKET. Instrukcja if w poprzednim kodzie służy do przechwytywania wszelkich błędów, które mogą wystąpić podczas tworzenia gniazda. WSAGetLastError zwraca numer błędu skojarzony z ostatnim błędem, który wystąpił.

Notatka

W zależności od aplikacji może być konieczne bardziej rozbudowane sprawdzanie błędów.

Na przykład ustawienie hints.ai_family do AF_UNSPEC może spowodować niepowodzenie podczas próby nawiązania połączenia. W takim przypadku należy użyć określonej wartości IPv4 (AF_INET) lub IPv6 (AF_INET6).

WSACleanup służy do kończenie korzystania z biblioteki DLL WS2_32.

Następny krok: nawiązywanie połączenia z gniazdem

Początki z Winsock

Inicjowanie Winsock

Aplikacja kliencka Winsock