Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

Verbindungsloser Server

&pagelevel(3)&pagelevel

Die meisten Services arbeiten verbindungsorientiert. Einige Services basieren jedoch auf der Verwendung von Datagramm-Sockets und arbeiten somit verbindungslos.

In den Beispielprogrammen verwendet der Server die folgenden Funktionen der Socket- bzw. POSIX-Schnittstelle:

  • socket(): einen Socket erzeugen

  • bind(): einem Socket einen Namen zuordnen

  • recvfrom(): eine Nachricht von einem Socket lesen

  • close(): einen Socket schließen

Das Programm wird in zwei Varianten vorgestellt:

  • In Beispiel 1 wird das Programm beendet, nachdem eine Nachricht gelesen wurde.

  • In Beispiel 2 wartet das Programm in einer Endlosschleife auf weitere Nachrichten, nachdem eine Nachricht gelesen wurde.

Beispiel 1: Verbindungsloser Server ohne Programmschleife

#include <stdio.h>
#include <sys/socket.h>
#include <ioctl.h>
#include <signal.h>
#include <netinet/in.h>
#include <netdb.h>
#define ERROR_EXIT(M) perror(M); exit(1)
#define TESTPORT 2222
int main(int argc, char **argv)
{
    int                sock;
    int                length;
    struct sockaddr_in server;
    char               buf[1024];
    /* Erzeugen des Sockets, von dem gelesen werden soll. */
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        ERROR_EXIT("socket");
    }
    /* Dem Socket unter Verwendung von Wildcards einen Namen zuordnen */
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(TESTPORT);
    if (bind(sock, (struct sockaddr *)&server, sizeof server ) < 0) {
        ERROR_EXIT("bind");
    }
    /* Lesens vom Server */
    length = sizeof(server);
    memset(buf,0,sizeof(buf));
    if (recvfrom(sock, buf, 1024, 0, (struct sockaddr *)&server, &length) < 0) {
        ERROR_EXIT("recvfrom");
    } else {
        printf("->%s\n",buf);
    }
    close(sock);
    return 0;
} 

Beispiel 2: Verbindungsloser Server mit Programmschleife

Da dieses Programm in einer Endlos-Schleife läuft, wird der Socket niemals explizit geschlossen. Allerdings werden alle Sockets automatisch geschlossen, wenn der Prozess abgebrochen wird oder sein normales Ende erreicht.

#include <sys/socket.h>
#include <ioctl.h>
#include <signal.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#define ERROR_EXIT(M) perror(M); exit(1)
#define TESTPORT 2222
int main(int argc, char **argv)
{
    int                sock;
    int                length;
    struct sockaddr_in server;
    char               buf[1024];
    /* Erzeugen des Sockets, von dem gelesen werden soll. */
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        ERROR_EXIT("socket");
    }
    /* Dem Socket unter Verwendung von Wildcards einen Namen zuordnen */
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(TESTPORT);
    if (bind(sock, (struct sockaddr *)&server, sizeof server ) < 0) {
        ERROR_EXIT("bind");
    }
    /* Beginn des Lesens vom Server */
    length = sizeof(server);
    for (;;) {
        memset(buf,0,sizeof(buf));
        if (recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&server, &length) < 0) {
            ERROR_EXIT("recvfrom");
        } else {
            printf("->%s\n",buf);
        }
    }
    /* NOTREACHED */
}

Im Programm werden folgende Arbeitsschritte durchgeführt:

  • Die Funktion socket() erzeugt einen Kommunikationsendpunkt (Server-Socket) und den zugehörigen Deskriptor.

  • Die Funktion bind() weist dem Server-Socket eine definierte Portnummer zu, sodass er über diese Portnummer vom Netzwerk aus angesprochen werden kann.
  • Mit der Funktion recvfrom() wird von einem Socket des Typs SOCK_DGRAM gelesen. Als Ergebnis wird die Länge der gelesenen Nachricht geliefert.
  • Wenn keine Nachricht vorhanden ist, wird der Prozess blockiert, bis eine Nachricht eintrifft.

Die Beispielprogramme sind nur für die Kommunikationsdomäne AF_INET gültig. Wenn sie gemäß den Angaben in "Socket- Adressierung" und "Socket erzeugen" geändert werden, gelten sie auch für die Domäne AF_INET6.