Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
System hosta serwera to komputer, który wykonuje program serwera aplikacji rozproszonej. W sieci może istnieć jeden lub wiele systemów hostów serwerów. Sposób, w jaki program kliencki znajdzie serwer do nawiązania połączenia, zależy od potrzeb programu.
Istnieją dwie metody znajdowania systemów hostów serwerów:
- Używanie informacji przechowywanych w ciągach w kodzie źródłowym klienta, zmiennych środowiskowych lub plikach konfiguracji specyficznych dla aplikacji. Aplikacja kliencka może stosować dane w stringu, aby utworzyć powiązanie między klientem a serwerem.
- Przeszukiwanie bazy danych usługi katalogowej w celu zlokalizowania programu serwera.
W tej sekcji przedstawiono informacje na temat obu tych technik w następujących tematach:
Używanie powiązań stringów
Aplikacje mogą tworzyć powiązania na podstawie informacji przechowywanych w ciągach. Aplikacja kliencka komponuje te informacje jako ciąg, a następnie wywołuje funkcję RpcBindingFromStringBinding. Klient musi podać następujące informacje, aby zidentyfikować serwer:
- Nazwa interfejsu, globalnie unikatowy identyfikator (GUID) obiektu lub UUID obiektu. Aby uzyskać więcej informacji, zobacz Generowanie identyfikatorów UUID interfejsu i identyfikatorów UUID ciągu .
- Typ transportu do komunikacji, taki jak nazwane potoki lub TCP/IP. Aby uzyskać szczegółowe informacje, zobacz Podstawowa terminologia dotycząca powiązań RPC i Wybieranie sekwencji protokołów.
- Adres sieciowy lub nazwa komputera hosta serwera.
- Punkt końcowy programu serwera na komputerze hosta serwera. Aby uzyskać więcej informacji, zobacz Znajdowanie punktów końcowychi Określanie punktów końcowych.
(Identyfikator UUID obiektu i informacje o punkcie końcowym są opcjonalne).
W poniższych przykładach parametr pszNetworkAddress i inne parametry obejmują osadzone ukośniki odwrotne. Ukośnik odwrotny jest znakiem ucieczki w języku programowania C. Aby poprawnie reprezentować każdy pojedynczy znak ukośnika odwrotnego, potrzebne są dwa ukośniki odwrotne. Struktura powiązania ciągów musi zawierać cztery znaki ukośnika odwrotnego, aby przedstawiać dwa dosłowne znaki ukośnika odwrotnego, które poprzedzają nazwę serwera.
W poniższym przykładzie pokazano, że nazwa serwera musi być poprzedzona ośmioma znakami ukośnika odwrotnego, aby cztery dosłowne znaki ukośnika odwrotnego pojawiły się w strukturze danych łańcucha powiązań po przetworzeniu ciągu przez funkcję sprintf_s.
/* client application */
char * pszUuid = "6B29FC40-CA47-1067-B31D-00DD010662DA";
char * pszProtocol = "ncacn_np";
char * pszNetworkAddress = "\\\\\\\\servername";
char * pszEndpoint = "\\\\pipe\\\\pipename";
char * pszString;
int len = 0;
len = sprintf_s(pszString, strlen(pszUuid), "%s", pszUuid);
len += sprintf_s(pszString + len, strlen(pszProtocolSequence) + 2, "@%s:",
pszProtocolSequence);
if (pszNetworkAddress != NULL)
len += sprintf_s(pszString + len, strlen(pszNetworkAddress), "%s",
pszNetworkAddress);
len += sprintf_s(pszString + len, strlen(pszEndpoint) + 2, "[%s]", pszEndpoint);
W poniższym przykładzie powiązanie ciągu jest wyświetlane jako:
6B29FC40-CA47-1067-B31D-00DD010662DA@ncacn_np:\\\\nazwa serwera[\\pipe\\nazwa pipe]
Następnie klient wywołuje RpcBindingFromStringBinding w celu uzyskania uchwytu powiązania:
RPC_BINDING_HANDLE hBinding;
status = RpcBindingFromStringBinding(pszString, &hBinding);
//...
Funkcja pomocnicza, RpcStringBindingCompose komponuje identyfikator UUID obiektu, sekwencję protokołu, adres sieciowy i punkt końcowy w poprawnej składni do wywołania RpcBindingFromStringBinding. Nie musisz martwić się o umieszczenie ampersanda, dwukropka i różnych składników dla każdej sekwencji protokołu w odpowiednim miejscu; wystarczy podać ciągi jako parametry funkcji. Biblioteka czasu wykonywania przydziela nawet pamięć wymaganą do powiązania łańcucha znaków.
char * pszNetworkAddress = "\\\\server";
char * pszEndpoint = "\\pipe\\pipename";
status = RpcStringBindingCompose(
pszUuid,
pszProtocolSequence,
pszNetworkAddress,
pszEndpoint,
pszOptions,
&pszString);
//...
status = RpcBindingFromStringBinding(
pszString,
&hBinding);
//...
Inna funkcja wygody, RpcBindingToStringBindingBinding, przyjmuje uchwyt powiązania jako dane wejściowe i tworzy odpowiednie powiązanie ciągu.
Importowanie z baz danych usługi nazw
Bazy danych usługi nazw przechowują między innymi dojścia powiązań i identyfikatory UUID. Aplikacja kliencka może wyszukać oba te elementy, jeśli musi być powiązana z serwerem. Aby zapoznać się z omówieniem informacji, które przechowuje usługa nazw oraz formatem przechowywania, zobacz Baza danych usługi nazw RPC.
Biblioteka RPC udostępnia dwa zestawy funkcji, których program kliencki może użyć do przeszukiwania bazy danych usługi nazw. Nazwy jednego zestawu zaczynają się od RpcNsBindingImport. Nazwy drugiego zestawu zaczynają się od RpcNsBindingLookup. Różnica między dwiema grupami funkcji polega na tym, że funkcje RpcNsBindingImport zwracają pojedynczy uchwyt powiązania na wywołanie, a funkcje RpcNsBindingLookup zwracają grupy uchwytów powiązania na wywołanie.
Aby rozpocząć wyszukiwanie za pomocą funkcji RpcNsBindingImport, najpierw wywołaj metodę RpcNsBindingImportBegin, jak pokazano w poniższym fragcie kodu.
RPC_STATUS status;
RPC_NS_HANDLE hNameServiceHandle;
status = RpcNsBindingImportBegin(
RPC_C_NS_SYNTAX_DEFAULT,
NULL,
MyInterface_v1_0_c_ifspec,
NULL,
&hNameServiceHandle);
Gdy funkcje RPC przeszukują bazę danych usługi nazw, potrzebują miejsca, aby rozpocząć wyszukiwanie. W terminologii RPC jest to nazywane nazwą wpisu. Program kliencki przekazuje nazwę wpisu jako drugi parametr do RpcNsBindingImportBegin. Ten parametr może być null, jeśli chcesz przeszukać całą bazę danych usługi nazw. Alternatywnie można przeszukać wpis serwera, przekazując nazwę wpisu serwera lub wyszukując wpis grupy, przekazując nazwę wpisu grupy. Przekazywanie nazwy wpisu ogranicza wyszukiwanie do zawartości tego wpisu.
W poprzednim przykładzie wartość RPC_C_NS_SYNTAX_DEFAULT jest przekazywana jako pierwszy parametr do RpcNsBindingImportBegin. Spowoduje to wybranie domyślnej składni nazwy wpisu. Obecnie jest to jedyna obsługiwana składnia nazw wpisów.
Aplikacja kliencka może przeszukiwać bazę danych usługi nazw w poszukiwaniu nazwy interfejsu, identyfikatora UUID lub obu tych elementów. Jeśli chcesz wyszukać interfejs według nazwy, przekaż globalną zmienną interfejsu generowaną przez kompilator MIDL z pliku IDL jako trzeci parametr do funkcji RpcNsBindingImportBegin. Jego deklaracja znajduje się w pliku nagłówkowym, który kompilator MIDL wygenerował podczas generowania wycinku klienta. Jeśli chcesz, aby program kliencki wyszukiwał tylko według identyfikatora UUID, ustaw trzeci parametr na wartość null.
Podczas przeszukiwania bazy danych usługi nazw dla identyfikatora UUID ustaw wartość czwartego parametru RpcNsBindingImportBegin na wartość identyfikatora UUID, którego szukasz. Jeśli nie wyszukujesz identyfikatora UUID, ustaw ten parametr na wartość null.
Funkcja RpcNsBindingImportBegin przekazuje adres uchwytu kontekstu wyszukiwania w usłudze nazw za pośrednictwem piątego parametru. Ten parametr jest przekazywany do innych funkcji RpcNsBindingImport.
W szczególności następną funkcją wywoływaną przez aplikację kliencką jest RpcNsBindingImportNext. Programy klienckie używają tej funkcji do pobierania zgodnych dojść powiązań z bazy danych usługi nazw. Poniższy fragment kodu pokazuje, jak można wywołać tę funkcję:
RPC_STATUS status;
RPC_BINDING_HANDLE hBindingHandle;
// The variable hNameServiceHandle is a valid name service search
// context handle obtained from the RpcNsBindingBegin function.
status = RpcNsBindingImportNext(hNameServiceHandle, &hBindingHandle);
Po wywołaniu funkcji RpcNsBindingImportNext w celu uzyskania uchwytu powiązania aplikacja kliencka może określić, czy uchwyt otrzymany jest akceptowalny. Jeśli nie, program kliencki może wykonać pętlę i ponownie wywołać RpcNsBindingImportNext, aby sprawdzić, czy usługa nazw zawiera bardziej odpowiednie dojście. Dla każdego wywołania RpcNsBindingImportNextmusi istnieć odpowiednie wywołanie RpcNsBindingFree. Po zakończeniu wyszukiwania wywołaj funkcję RpcNsBindingImportDone, aby zwolnić kontekst wyszukiwania.
Gdy aplikacja kliencka ma akceptowalny uchwyt powiązania, należy sprawdzić, czy aplikacja serwera jest uruchomiona. Istnieją dwie metody, których klient może użyć do przeprowadzenia tej weryfikacji. Pierwszą z nich jest wywołanie funkcji w interfejsie klienta. Jeśli program serwera jest uruchomiony, wywołanie zostanie zakończone. Jeśli nie, wywołanie zakończy się niepowodzeniem. Lepszym sposobem sprawdzenia, czy serwer jest uruchomiony, jest wywołanie RpcEpResolveBinding, a następnie wywołanie RpcMgmtIsServerListening. Aby uzyskać więcej informacji na temat bazy danych usługi nazw, zobacz Baza danych usługi nazw RPC.