In diesen Programmbeispielen verwendet der Client die folgenden Funktionen der Socket-Schnittstelle:
socket(): Socket erzeugen
gethostbyname() / getipnodebyname(): Rechner-Eintrag abfragen
sendto(): Nachricht an einen Socket senden
soc_close(): Socket schließen
Beispiel: Verbindungsloser Client bei 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 DATA " The sea is calm, the tide is full ..." #define TESTPORT 2222 /* * Dieses Programm sendet ein Datagramm an einen Empfänger, dessen Name als * Argument in der Kommandozeile übergeben wird. */ main(argc,argv) int argc; char *argv[]; { int sock; struct sockaddr_in to; struct hostent *hp, *gethostbyname(); /* Erzeugen des Sockets, an den gesendet werden soll. */ sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0 ) { perror("Socket datagram"); exit(1); } /* Konstruieren des Namens des Sockets, an den gesendet werden soll, * ohne Verwendung von Wildcards. gethostbyname liefert eine Struktur, * die die Netzadresse des angegebenen Rechners enthält. * Die Portnummer wird aus der Konstante TESTPORT entnommen. */ hp =gethostbyname(argv[1]); if (hp == 0) { fprintf(stderr, "%s:unknown host\n", argv[1]); exit(1); } memcpy((char *)&to.sin_addr, (char *)hp->h_addr,hp->h_length); to.sin_family = AF_INET; to.sin_port = htons(TESTPORT); /* Nachricht senden. */ if (sendto(sock, DATA, sizeof DATA, 0, &to, sizeof to) < 0) { perror("Sending datagram message"); exit(1); } soc_close(sock); }
Beispiel: Verbindungsloser Client bei 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 DATA " The sea is calm, the tide is full ..." #define TESTPORT 2222 /* * Dieses Programm sendet ein Datagramm an einen Empfänger, dessen Name als * Argument in der Kommandozeile übergeben wird. */ main(argc,argv) int argc; char *argv[]; { int sock; int error_num; struct sockaddr_in6 to; struct hostent *hp; /* Erzeugen des Sockets, an den gesendet werden soll. */ sock = socket(AF_INET6, SOCK_DGRAM, 0); if (sock < 0 ) { perror("Socket datagram"); exit(1); } /* Konstruieren des Namens des Sockets, an den gesendet werden soll, * ohne Verwendung von Wildcards. gethostbyname liefert eine Struktur, * die die Netzadresse des angegebenen Rechners enthält. * Die Portnummer wird aus der Konstante TESTPORT entnommen. */ hp =getipnodebyname(argv[1], AF_INET6, 0, &error_num); if ((hp = = 0) || (error_num != NETDB_SUCCESS)) { fprintf(stderr, "%s:unknown host\n", argv[1]); exit(1); } memcpy((char *)&to.sin6_addr, (char *)hp->h_addr,hp->h_length); to.sin6_family = AF_INET6; to.sin6_port = htons(TESTPORT); /* Freigabe des dynamischen Speichers von hostent */ freehostent(hp); /* Nachricht senden. */ if (sendto(sock, DATA, sizeof DATA, 0, &to, sizeof to) < 0) { perror("Sending datagram message"); exit(1); } soc_close(sock); }
In den Programmbeispielen zu AF_INET und AF_INET6 werden folgende Arbeitsschritte durchgeführt:
- Der Client erzeugt mit socket() einen Kommunikationsendpunkt (Socket) und den zugehörigen Deskriptor.
Mit gethostbyname() fragt der Client die Adresse des Rechners ab (bei AF_INET); es wird der Rechnername als Parameter übergeben.
Mit getipnodebyname() fragt der Client die IPv6-Adresse des als Parameter übergebenen Rechnernamens ab. DIese neue Funktion könnte auch für das AF_INET Beispiel verwendet werden.
Danach wird die Adress-Struktur initialisiert.Mit sendto() sendet der Client ein Datagramm. sendto() liefert die Anzahl der übertragenen Zeichen zurück.
Mit soc_close() schließt der Client den Socket.