PGM-Absender und -Empfänger
Das Einrichten einer PGM-Sitzung ähnelt der Verbindungsherstellungsroutine, die einer TCP-Sitzung zugeordnet ist. Die wesentliche Abkehr von einer TCP-Sitzung besteht jedoch darin, dass die Client- und Serversemantik umgekehrt sind. Der Server (der PGM-Absender) stellt eine Verbindung mit einer Multicastgruppe her, während der Client (der PGM-Empfänger) wartet, um eine Verbindung zu akzeptieren. In den folgenden Absätzen werden die programmgesteuerten Schritte beschrieben, die zum Erstellen eines PGM-Absenders und eines PGM-Empfängers erforderlich sind. Auf dieser Seite werden auch die verfügbaren Datenmodi für PGM-Sitzungen beschrieben.
PGM-Absender
Führen Sie die folgenden Schritte aus, um einen PGM-Absender zu erstellen:
- Erstellen Sie einen PGM-Socket.
- Binden Sie den Socket an INADDR_ANY.
- Stellen Sie eine Verbindung mit der Multicastgruppenübertragungsadresse her.
Es wird kein formelles Sitzungshandshake mit Clients ausgeführt. Der Verbindungsprozess ähnelt einer UDP-Verbindung, da er dem Socket eine Endpunktadresse (die Multicastgruppe) zuordnet. Nach Abschluss des Vorgangs können Daten auf dem Socket gesendet werden.
Wenn ein Absender einen PGM-Socket erstellt und mit einer Multicastadresse verbindet, wird eine PGM-Sitzung erstellt. Eine zuverlässige Multicastsitzung wird durch eine Kombination aus der GUID (Globally Unique Identifier) und dem Quellport definiert. Die GUID wird vom Transport generiert. Der sSource-Port wird durch den Transport angegeben, und es wird keine Kontrolle darüber bereitgestellt, welcher Quellport verwendet wird.
Hinweis
Das Empfangen von Daten auf einem Absendersocket ist nicht zulässig und führt zu einem Fehler.
Der folgende Codeausschnitt veranschaulicht das Einrichten eines PGM-Absenders:
SOCKET s;
SOCKADDR_IN salocal, sasession;
int dwSessionPort;
s = socket (AF_INET, SOCK_RDM, IPPROTO_RM);
salocal.sin_family = AF_INET;
salocal.sin_port = htons (0); // Port is ignored here
salocal.sin_addr.s_addr = htonl (INADDR_ANY);
bind (s, (SOCKADDR *)&salocal, sizeof(salocal));
//
// Set all relevant sender socket options here
//
//
// Now, connect <entity type="hellip"/>
// Setting the connection port (dwSessionPort) has relevance, and
// can be used to multiplex multiple sessions to the same
// multicast group address over different ports
//
dwSessionPort = 0;
sasession.sin_family = AF_INET;
sasession.sin_port = htons (dwSessionPort);
sasession.sin_addr.s_addr = inet_addr ("234.5.6.7");
connect (s, (SOCKADDR *)&sasession, sizeof(sasession));
//
// We're now ready to send data!
//
PGM-Empfänger
Führen Sie zum Erstellen eines PGM-Empfängers die folgenden Schritte aus:
- Erstellen Sie einen PGM-Socket.
- Binden Sie den Socket an die Multicastgruppenadresse, an die der Absender sendet.
- Rufen Sie die Listenfunktion im Socket auf, um den Socket in den Lauschmodus zu versetzen. Die Listenfunktion gibt zurück, wenn eine PGM-Sitzung für die angegebene Multicastgruppenadresse und den angegebenen Port erkannt wird.
- Rufen Sie die accept-Funktion auf, um ein neues Sockethandle zu erhalten, das der Sitzung entspricht.
Nur originale PGM-Daten (ODATA) lösen die Annahme einer neuen Sitzung aus. Daher wird möglicherweise anderer PGM-Datenverkehr (z. B. SPM- oder RDATA-Pakete) vom Transport empfangen, führt jedoch nicht dazu, dass die Listenfunktion zurückgegeben wird.
Sobald eine Sitzung akzeptiert wurde, wird das zurückgegebene Sockethandle zum Empfangen von Daten verwendet.
Hinweis
Das Senden von Daten auf einem Empfangssocket ist nicht zulässig und führt zu einem Fehler.
Der folgende Codeausschnitt veranschaulicht das Einrichten eines PGM-Empfängers:
SOCKET s,
sclient;
SOCKADDR_IN salocal,
sasession;
int sasessionsz, dwSessionPort;
s = socket (AF_INET, SOCK_RDM, IPPROTO_RM);
//
// The bind port (dwSessionPort) specified should match that
// which the sender specified in the connect call
//
dwSessionPort = 0;
salocal.sin_family = AF_INET;
salocal.sin_port = htons (dwSessionPort);
salocal.sin_addr.s_addr = inet_addr ("234.5.6.7");
bind (s, (SOCKADDR *)&salocal, sizeof(salocal));
//
// Set all relevant receiver socket options here
//
listen (s, 10);
sasessionsz = sizeof(sasession);
sclient = accept (s, (SOCKADDR *)&sasession, &sasessionsz);
//
// accept will return the client socket and we are now ready
// to receive data on the new socket!
//
Datenmodi
PGM-Sitzungen haben zwei Optionen für Datenmodi: Nachrichtenmodus und Streammodus.
Der Nachrichtenmodus eignet sich für Anwendungen, die diskrete Nachrichten senden müssen, und wird durch einen Sockettyp von SOCK_RDM angegeben. Der Streammodus eignet sich für Anwendungen, die Streamingdaten an Empfänger senden müssen, z. B. Video- oder Sprachanwendungen, und wird durch einen Sockettyp von SOCK_STREAM angegeben. Die Wahl des Modus wirkt sich auf die Verarbeitung von Daten durch Winsock aus.
Betrachten Sie das folgende Beispiel: Ein PGM-Absender im Nachrichtenmodus führt drei Aufrufe an die WSASend-Funktion aus, die jeweils einen 100-Byte-Puffer aufweisen. Dieser Vorgang wird in der Verbindung als drei separate PGM-Pakete angezeigt. Auf der Empfängerseite gibt jeder Aufruf der WSARecv-Funktion nur 100 Bytes zurück, auch wenn ein größerer Empfangspuffer bereitgestellt wird. Im Gegensatz dazu könnten bei einem PGM-Sender im Streammodus diese drei 100-Byte-Übertragungen zu weniger als drei physischen Paketen auf der Leitung zusammengeführt werden (oder auf der Empfängerseite zu einem Datenblob zusammengeführt werden). Wenn der Empfänger also eine der Empfangsfunktionen von Windows Sockets aufruft, kann jede vom PGM-Transport empfangene Datenmenge an die Anwendung zurückgesendet werden, ohne rücksichtslos darauf zu achten, wie die Daten physisch übertragen oder empfangen wurden.