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

In den meisten Fällen arbeiten Server verbindungsorientiert. Einige Services basieren jedoch auf der Verwendung von Datagramm-Sockets und arbeiten somit verbindungslos.

In den Programmbeispielen verwendet der Server die folgenden Funktionen der Socket-Schnittstelle:

  • socket(): Socket erzeugen

  • bind(): einem Socket einen Namen zuordnen

  • recvfrom(): Nachricht von einem Socket lesen

  • soc_close(): Socket schließen

Das Programm wird in zwei Varianten vorgestellt:

  • In der ersten Variante (Beispiele 1 und 3) wird das Programm beendet, wenn eine Nachricht ankommt (read()).

  • In der zweiten Variante (Beispiele 2 und 4) wartet das Programm in einer Endlosschleife auf weitere Nachrichten, nachdem eine Nachricht gelesen wurde.

   
Beispiel 1: Verbindungsloser Server ohne Programmschleife für AF_INET

#include <stdio.h>
#include <sys.types.h>
#include <sys.socket.h>
#include <ioctl.h>
#include <signal.h>
#include <netinet.in.h>
#include <netdb.h>
   
#define TESTPORT 2222
   
/*
 * Dieses Programm erzeugt einen Datagramm-Socket, ordnet ihm einen 
 * definierten Port zu und liest dann Daten vom Socket.
 */
  
main()
{
   int sock;
   int length;
    struct sockaddr_in server;
    char buf[1024];
  
/* Erzeugen des Sockets, von dem gelesen werden soll. */
    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0 )
       { perror("Socket datagram");
         exit(1);
       }
   
    /* Dem Server "server" 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, &server, sizeof server ) < 0)
       { perror("Bind datagram socket");
         exit(1);
       }
   
    /* Beginn des Lesens vom Server */
    length = sizeof(server);
    memset(buf,0,sizeof(buf));
    if ( recvfrom(sock, buf, 1024,0, &server, &length) < 0 )
           { perror("recvfrom");
             exit(1);
           }
    else
          printf("->%s\n",buf);
    soc_close(sock);
}

 
Beispiel 2: Verbindungsloser Server mit Programmschleife für AF_INET

#include <sys.types.h>
#include <sys.socket.h>
#include <ioctl.h>
#include <signal.h>
#include <netinet.in.h>
#include <netdb.h>
#include <stdio.h>
#define TESTPORT 2222
  
/* Dieses Programm erzeugt einen Datagramm-Socket, ordnet ihm einen 
 * definierten Port zu und liest dann Daten vom Socket.  */
main()
{
    int sock;
    int length;
    struct sockaddr_in server;
    char buf[1024];
  
    /* Erzeugen des Sockets, von dem gelesen werden soll. */
    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0 )
       { perror("Socket datagram");
         exit(1);
       }
  
    /* Dem Server "server" 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, &server, sizeof server ) < 0)
       { perror("Bind datagram socket");
         exit(1);
       }
  
    /* Beginn des Lesens vom Server */
    length = sizeof(server);
    for (;;)
    {
        memset(buf,0,sizeof(buf));
        if ( recvfrom(sock, buf, sizeof(buf),0, &server, &length) < 0 )
              {  perror("recvfrom");
                 exit(1);
              }
        else
              printf("->%s\n",buf);
    }
  
    /* Da dieses Programm in einer Endlos-Schleife läuft, wird der 
     * Socket "sock" niemals explizit geschlossen. Allerdings werden alle 
     * Sockets automatisch geschlossen, wenn der Prozess abgebrochen wird. 
     */
}

  

Beispiel 3: Verbindungsloser Server ohne Programmschleife für AF_INET6

#include <stdio.h>
#include <sys.types.h>
#include <sys.socket.h>
#include <ioctl.h>
#include <signal.h>
#include <netinet.in.h>
#include <netdb.h>
#define TESTPORT 2222
  
/*
* Dieses Programm erzeugt einen Datagramm-Socket, ordnet ihm einen
* definierten Port zu und liest dann Daten vom Socket.
*/
   
main()
{
    int sock;
    int length;
    struct sockaddr_in6 server;
    struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
    char buf[1024];
  
    /* Erzeugen des Sockets, von dem gelesen werden soll. */
    sock = socket(AF_INET6, SOCK_DGRAM, 0);
    if (sock < 0 )
       { perror("Socket datagram");
         exit(1);
       }
  
    /* Dem Server "server" unter Verwendung von Wildcards einen Namen 
    zuordnen */
    server.sin6_family = AF_INET6;
    memcpy(server.sin6_addr.s6_addr, in6addr_any.s6_addr, 16) ;
    server.sin6_port = htons(TESTPORT);
    if (bind(sock, &server, sizeof server ) < 0)
       { perror("Bind datagram socket");
         exit(1); 
       }
  
    /* Beginn des Lesens vom Server */
    length = sizeof(server);
    memset(buf,0,sizeof(buf));
    if ( recvfrom(sock, buf, 1024,0, &server, &length) < 0 )
       { perror("recvfrom");
         exit(1);
       }
    else
       printf("->%s\n",buf);
    soc_close(sock);
}

Beispiel 4: Verbindungsloser Server mit Programmschleife für AF_INET6

#include <sys.types.h>
#include <sys.socket.h>
#include <ioctl.h>
#include <signal.h>
#include <netinet.in.h>
#include <netdb.h>
#include <stdio.h>
  
#define TESTPORT 2222
  
/* Dieses Programm erzeugt einen Datagramm-Socket, ordnet ihm einen
 * definierten Port zu und liest dann Daten vom Socket. */
  
main()
{
    int sock;
    int length;
    struct sockaddr_in6 server;
    struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
    char buf[1024];
   
    /* Erzeugen des Sockets, von dem gelesen werden soll. */
  
    sock = socket(AF_INET6, SOCK_DGRAM, 0);
    if (sock < 0 )
       {
         perror("Socket datagram");
         exit(1);
       }
  
    /* Dem Server "server" unter Verwendung von Wildcards einen
    * Namen zuordnen */
  
    server.sin6_family = AF_INET6;
    memcpy(server.sin6_addr.s6_addr ,in6addr_any.s6_addr,16);
    server.sin6_port = htons(TESTPORT);
    if (bind(sock, &server, sizeof server ) < 0)
       {
         perror("Bind datagram socket");
         exit(1);
       }
  
    /* Beginn des Lesens vom Server */
  
    length = sizeof(server);
    for (;;)
       {
         memset(buf,0,sizeof(buf));
         if ( recvfrom(sock, buf, sizeof(buf),0, &server, &length) < 0 )
           {
             perror("recvfrom");
             exit(1);
         else
             printf("->%s\n",buf);
       }
  
    /* Da dieses Programm in einer Endlos-Schleife läuft, wird der
     * Socket "sock" niemals explizit geschlossen. Allerdings werden alle
     * Sockets automatisch geschlossen, wenn der Prozess abgebrochen wird.
     */
}

In den Programmbeispielen zu AF_INET und AF_INET6 werden folgende Arbeitsschritte durchgeführt:

  1. Der Server erzeugt mit der Funktion socket() einen Kommunikationsendpunkt (Socket) und den zugehörigen Deskriptor.
  2. Mit der Funktion bind() wird dem Server-Socket eine definierte Portnummer zugeordnet, sodass er über diese Portnummer vom Netz aus adressiert werden kann.

  3. Von einem Socket des Typs SOCK_DGRAM kann mit der Funktion recvfrom() gelesen werden.

  4. Als Ergebnis wird die Länge der gelesenen Nachricht geliefert. Wenn keine Nachricht vorhanden ist, wird der Prozess blockiert, bis eine Nachricht eintrifft.