Suchen von Serverhostsystemen
Ein Serverhostsystem ist der Computer, der das Serverprogramm der verteilten Anwendung ausführt. Es kann ein oder mehrere Serverhostsysteme in einem Netzwerk geben. Wie Ihr Clientprogramm einen Server findet, mit dem eine Verbindung hergestellt werden kann, hängt von den Anforderungen Ihres Programms ab.
Es gibt zwei Methoden zum Suchen von Serverhostsystemen:
- Verwenden von Informationen, die in Zeichenfolgen im Clientquellcode, in Umgebungsvariablen oder in anwendungsspezifischen Konfigurationsdateien gespeichert sind. Ihre Clientanwendung kann die Daten in der Zeichenfolge verwenden, um eine Bindung zwischen dem Client und dem Server zu erstellen.
- Abfragen einer Namensdienstdatenbank nach dem Speicherort eines Serverprogramms.
Dieser Abschnitt enthält Informationen zu beiden Verfahren in den folgenden Themen:
Verwenden von Zeichenfolgenbindungen
Anwendungen können Bindungen aus in Zeichenfolgen gespeicherten Informationen erstellen. Ihre Clientanwendung erstellt diese Informationen als Zeichenfolge und ruft dann die RpcBindingFromStringBinding-Funktion auf. Der Client muss die folgenden Informationen bereitstellen, um den Server zu identifizieren:
- Der Schnittstellenname, der GUID (Globally Unique Identifier) des Objekts oder die UUID des Objekts. Weitere Informationen finden Sie unter Generieren von Schnittstellen-UUIDs und String UUID.
- Der zu kommunizierende Transporttyp, z. B. Named Pipes oder TCP/IP. Weitere Informationen finden Sie unter Grundlegende RPC-Bindungsterminologie und Auswählen einer Protokollsequenz.
- Die Netzwerkadresse oder der Name des Serverhostcomputers.
- Der Endpunkt des Serverprogramms auf dem Serverhostcomputer. Weitere Informationen finden Sie unter Suchen von Endpunktenund Angeben von Endpunkten.
(Die Objekt-UUID und die Endpunktinformationen sind optional.)
In den folgenden Beispielen enthalten der pszNetworkAddress-Parameter und andere Parameter eingebettete umgekehrte Schrägstriche. Der umgekehrte Schrägstrich ist ein Escapezeichen in der Programmiersprache C. Zwei umgekehrte Schrägstriche sind erforderlich, um jeden einzelnen literalen umgekehrten Schrägstrich darzustellen. Die Zeichenfolgenbindungsstruktur muss vier umgekehrte Schrägstriche enthalten, um die beiden literalen umgekehrten Schrägstriche darzustellen, die dem Servernamen vorangestellt sind.
Das folgende Beispiel zeigt, dass dem Servernamen acht umgekehrte Schrägstriche vorangestellt werden müssen, damit vier literale umgekehrte Schrägstriche in der Zeichenfolgenbindungsdatenstruktur angezeigt werden, nachdem die _ Sprintf-Funktion die Zeichenfolge verarbeitet hat.
/* 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);
Im folgenden Beispiel wird die Zeichenfolgenbindung wie folgt angezeigt:
6B29FC40-CA47-1067-B31D-00DD010662DA@ncacn_np: \ \ \ \ servername [ \ \ pipe \ \ pipename]
Der Client ruft dann RpcBindingFromStringBinding auf, um das Bindungshandle abzurufen:
RPC_BINDING_HANDLE hBinding;
status = RpcBindingFromStringBinding(pszString, &hBinding);
//...
Die Funktion RpcStringBindingCompose stellt die Objekt-UUID, die Protokollsequenz, die Netzwerkadresse und den Endpunkt in der richtigen Syntax für den Aufruf von RpcBindingFromStringBindingzusammen. Sie müssen sich nicht darum kümmern, das Ampersand, den Doppelpunkt und die verschiedenen Komponenten für jede Protokollsequenz an der richtigen Stelle zu platzieren. Sie stellen nur die Zeichenfolgen als Parameter für die Funktion bereit. Die Laufzeitbibliothek belegt sogar den Arbeitsspeicher, der für die Zeichenfolgenbindung benötigt wird.
char * pszNetworkAddress = "\\\\server";
char * pszEndpoint = "\\pipe\\pipename";
status = RpcStringBindingCompose(
pszUuid,
pszProtocolSequence,
pszNetworkAddress,
pszEndpoint,
pszOptions,
&pszString);
//...
status = RpcBindingFromStringBinding(
pszString,
&hBinding);
//...
Eine weitere praktische Funktion, RpcBindingToStringBinding,nimmt ein Bindungshandle als Eingabe und erzeugt die entsprechende Zeichenfolgenbindung.
Importieren aus Namensdienstdatenbanken
Namensdienstdatenbanken speichern unter anderem Bindungshandles und UUIDs. Ihre Clientanwendung kann entweder oder beides suchen, wenn sie eine Bindung an den Server herstellen muss. Eine Erläuterung der Informationen, die ein Namensdienst speichert, und des Speicherformats finden Sie unter The RPC Name Service Database.
Die RPC-Bibliothek stellt zwei Sätze von Funktionen bereit, mit denen Ihr Clientprogramm die Namensdienstdatenbank durchsuchen kann. Die Namen einer Gruppe beginnen mit RpcNsBindingImport. Die Namen der anderen Gruppe beginnen mit RpcNsBindingLookup. Der Unterschied zwischen den beiden Funktionsgruppen besteht darin, dass die RpcNsBindingImport-Funktionen ein einzelnes Bindungshandle pro Aufruf zurückgeben und die RpcNsBindingLookup-Funktionen Gruppen von Handles pro Aufruf zurückgeben.
Um eine Suche mit den RpcNsBindingImport-Funktionen zu starten, rufen Sie zunächst RpcNsBindingImportBeginauf, wie im folgenden Codefragment gezeigt.
RPC_STATUS status;
RPC_NS_HANDLE hNameServiceHandle;
status = RpcNsBindingImportBegin(
RPC_C_NS_SYNTAX_DEFAULT,
NULL,
MyInterface_v1_0_c_ifspec,
NULL,
&hNameServiceHandle);
Wenn die RPC-Funktionen die Namensdienstdatenbank durchsuchen, benötigen sie einen Ort, an dem die Suche beginnen kann. In der RPC-Terminologie wird dies als Eintragsname bezeichnet. Ihr Clientprogramm übergibt den Eintragsnamen als zweiten Parameter an RpcNsBindingImportBegin. Dieser Parameter kann NULL sein, wenn Sie die gesamte Name Service-Datenbank durchsuchen möchten. Alternativ können Sie den Servereintrag durchsuchen, indem Sie einen Servereintragsnamen übergeben, oder den Gruppeneintrag durchsuchen, indem Sie einen Gruppeneintragsnamen übergeben. Die Übergabe eines Eintragsnamens schränkt die Suche auf den Inhalt dieses Eintrags ein.
Im vorherigen Beispiel wird der Wert RPC _ C _ NS _ SYNTAX DEFAULT als erster Parameter an _ RpcNsBindingImportBeginübergeben. Dadurch wird die Standardsyntax für den Eintragsnamen ausgewählt. Derzeit ist dies die einzige unterstützte Syntax für Eintragsnamen.
Ihre Clientanwendung kann die Name-Dienstdatenbank nach einem Schnittstellennamen, einer UUID oder beiden suchen. Wenn Sie eine Schnittstelle anhand des Namens suchen möchten, übergeben Sie die globale Schnittstellenvariable, die der MIDL-Compiler aus Ihrer IDL-Datei generiert, als dritten Parameter an RpcNsBindingImportBegin. Sie finden seine Deklaration in der Headerdatei, die der MIDL-Compiler beim Generieren des Clientstubs generiert hat. Wenn Ihr Clientprogramm nur nach UUID suchen soll, legen Sie den dritten Parameter auf NULL fest.
Legen Sie beim Durchsuchen der Namensdienstdatenbank nach einer UUID den vierten Parameter von RpcNsBindingImportBegin auf die UUID fest, nach der Sie suchen möchten. Wenn Sie nicht nach einer UUID suchen, legen Sie diesen Parameter auf NULL fest.
Die RpcNsBindingImportBegin-Funktion übergibt die Adresse eines Namensdienst-Suchkontexthandle über ihren fünften Parameter. Sie übergeben diesen Parameter an andere RpcNsBindingImport-Funktionen.
Die nächste Funktion, die Ihre Clientanwendung aufrufen würde, ist rpcNsBindingImportNext. Clientprogramme verwenden diese Funktion, um kompatible Bindungshandles aus der Namensdienstdatenbank abzurufen. Das folgende Codefragment veranschaulicht, wie diese Funktion aufgerufen werden kann:
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);
Nachdem die RpcNsBindingImportNext-Funktion aufgerufen wurde, um ein Bindungshandle abzurufen, kann Ihre Clientanwendung ermitteln, ob das empfangene Handle akzeptabel ist. Andernfalls kann Ihr Clientprogramm eine Schleife ausführen und RpcNsBindingImportNext erneut aufrufen, um festzustellen, ob der Name-Dienst ein geeigneteres Handle enthält. Für jeden Aufruf von RpcNsBindingImportNext muss ein entsprechender Aufruf von RpcNsBindingFree vorhanden sein. Rufen Sie nach Abschluss der Suche die RpcNsBindingImportDone-Funktion auf, um den Suchkontext frei zu machen.
Nachdem Ihre Clientanwendung über ein akzeptables Bindungshandle verfügt, sollte sie überprüfen, ob die Serveranwendung ausgeführt wird. Es gibt zwei Methoden, mit denen Ihr Client diese Überprüfung durchführen kann. Die erste besteht darin, eine Funktion in der Clientschnittstelle aufzurufen. Wenn das Serverprogramm ausgeführt wird, wird der Aufruf abgeschlossen. Falls nicht, schlägt der Aufruf fehl. Eine bessere Möglichkeit, um zu überprüfen, ob der Server ausgeführt wird, besteht darin, RpcEpResolveBindingaufzurufen, gefolgt von einem Aufruf von RpcMgmtIsServerListening. Weitere Informationen zur Namensdienstdatenbank finden Sie unter The RPC Name Service Database.