Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger

 << zurück
Linux-UNIX-Programmierung von Jürgen Wolf
Das umfassende Handbuch – 2., aktualisierte und erweiterte Auflage 2006
Buch: Linux-UNIX-Programmierung

Linux-UNIX-Programmierung
1216 S., mit CD, 49,90 Euro
Rheinwerk Computing
ISBN 3-89842-749-8
gp Kapitel A Funktionsreferenz
  gp B.1 ANSI C
  gp B.2 ANSI C99
  gp B.3 Elementare E/A-Funktionen
  gp B.4 Fortgeschrittene Ein-/Ausgabe-Funktionen
  gp B.5 Verzeichnisse
  gp B.6 Attribute von Dateien und Verzeichnissen
  gp B.7 Links
  gp B.8 Prozess und Prozessverwaltungsfunktionen
  gp B.9 Signale – Das neue Signalkonzept
  gp B.10 Interprozesskommunikationen
  gp B.11 Sys-V-Interprozesskommnunikationen
  gp B.12 Threadprogrammierung
  gp B.13 Netzwerkprogrammierung
  gp B.14 MySQL C-API
  gp B.15 PostgreSQL C-API
  gp B.16 Weitere Funktionsreferenzen auf der Buch-CD


Rheinwerk Computing

B.13 Netzwerkprogrammierung  downtop


Rheinwerk Computing

B.13.1 Grundlegende Socket-Funktionen  downtop

Die gleich folgenden Funktionen zur Socket-Programmierung benötigen alle die Headerdateien:

#include <sys/types.h>
#include <sys/socket.h>

Des-Weiteren wird eine Struktur namens sockaddr verwendet, die wie folgt definiert ist:

struct sockaddr {
    sa_family_t  sa_family;   /* address family, AF_xxx       */
    char         sa_data[14]; /* 14 bytes of protocol address */
 };

Diese Struktur lässt sich allerdings recht unbequem ausfüllen (gemeint sind damit Portnummer und Internet-Adresse in der Strukturvariable sa_data), weshalb es für IP-Anwendungen eine spezielle Struktur dafür gibt:

struct sockaddr_in {
    sa_family_t sin_family;         /* Address-Familie  */
    unsigned short int sin_port;    /* Portnummer       */
    struct in_addr sin_addr;        /* Internet-Adresse */
};

sockaddr_in ermöglicht es Ihnen, die IP-Adresse sowie die Portnummer getrennt einzutragen. Im Speicher sind diese beiden Strukturen kompatibel, es reicht also eine einfache Typumwandlung, um die gewünschten Informationen zu übergeben.


Tabelle B.68    Grundlegende Socket-Funktionen

Syntax Bedeutung
int socket ( int domain, int type, int protocol ); Einen Socket (Endpunkt) zur Kommunikation anlegen
int bind ( int s, const struct sockaddr *name, int namelen ); Ein Socket mit einer Adresse verknüpfen (Server)
int listen(int s, int backlog); Am Socket horchen – auf eine Verbindung warten
int accept ( int s, struct sockaddr *addr, int *addrlen ); Eintreffende Verbindungswünsche bearbeiten
int connect ( int s, const struct sockaddr *name, int namelen ); Eine Verbindung zum Server herstellen (Client)
ssize_t send ( int s, const void *msg, size_t len, int flags ); Versenden von Daten über ein Socket
ssize_t sendto ( int s, const void *msg, size_t len, int flags, const struct sockaddr *to, int tolen ); Versenden von Daten über ein Socket (wird vorwiegend mit dem UDP-Protokoll verwendet)
ssize_t recv ( int s, void *buf, size_t len, int flags ); Empfangen von Daten über ein Socket
ssize_t recvfrom ( int s, void *buf, size_t len, int flags, struct sockaddr *from, int *fromlen ); Empfangen von Daten über ein Socket (wird vorwiegend mit dem UDP-Protokoll verwendet)
int getsockopt ( int s, int level, int optname, void *optval, int *optlen ); Erfragen von Optionen für Sockets
int setsockopt ( int s, int level, int optname, const void *optval, int optlen ); Setzen von Optionen für Sockets
int socketpair( int d, int type, int protocol, int sv[2]); Der Aufruf socketpair() generiert zwei unbenannte, miteinander verbundene Sockets. d bezeichnet die Domain, typ den Typ der Sockets und protocol definiert das Protokoll, das nicht angegeben werden muss. Die Deskriptoren der Sockets werden in sv[0] und sv[1] zurückgegeben. Die beiden Sockets können nicht unterschieden werden. Die Sematik der Funktion entspricht dem Syscall pipe().
int shutdown(int s, int how); shutdown() beendet eine ganze Voll-Duplex-Verbindung oder einen Teil einer Voll-Duplex-Verbindung, die mit dem Socket s verbunden ist. Ist how=0, so werden weitere empfangene Nachrichten abgelehnt. Ist how=1 , so werden weitere zu sendende Nachrichten abgelehnt. Ist how=2 , so werden zu sendende und empfangene Nachrichten abgelehnt.
int getpeername( int s, struct sockaddr *name, int *namelen ); getperrname() liefert zu einem gegebenen Socket s die Adresse des entfernten Endes. name ist ein Zeiger auf einen Speicherplatz, an dem das System die Adresse ablegen kann und namelen teilt dem System mit, wie viel Platz vorhanden ist. Daran erkennt es, welche Art von Adresse man erwartet. Da es sich um einen Wert/Ergebnis-Parameter handelt, muss er vorbelegt werden und unbedingt auf einen schreibbaren Speicherplatz zeigen.
int getsockname( int s, struct sockaddr *name, int *namelen); getsockname() liefert zu einem gegebenen Socket s die Adresse des lokalen Endes. name ist ein Zeiger auf einen Speicherplatz, an dem das System die Adresse ablegen kann und namelen teilt dem System mit, wie viel Platz vorhanden ist. Daran erkennt es, welche Art von Adresse man erwartet. Da es sich um einen Wert/Ergebnis-Parameter handelt, muss er vorbelegt werden und unbedingt auf einen schreibbaren Speicherplatz zeigen.


Rheinwerk Computing

B.13.2 Konvertieren zur richtigen Byteanordnung  downtop

Es gibt verschiedene Architekturen, in denen sich die Anordnung der Bytereihenfolge beim Abspeichern einer Zahl unterscheiden. Generell wird dabei zwischen Big Endian und Little Endian unterschieden. Beim Big Endian wird das höchstwertige Byte an der niedrigsten Adresse gespeichert, das zweithöchste an der nächsten Adressen und so weiter. Bei der Anordnung von Little Endian ist dies genau umgekehrt. Dabei wird das niedrigstwertige Byte an der niedrigsten Stelle gespeichert, das zweitniedrigste an der nächsten Stelle usw.

Damit sich jetzt aber alle Rechner untereinander verstehen, hat man sich auf eine einheitliche Datenübertragung mit Big Endian (auch als network-byte-order bezeichnet) geeinigt. Um jetzt aus einer lokal verwendeten Byte-Reihenfolge (host-byte-order) eine network-byte-order-Reihenfolge und umgekehrt zu konvertieren, stehen Ihnen die folgenden Funktionen zur Verfügung, welche alle die Headerdatei <netinet/in.h> benötigen.


Tabelle B.69    Funktionen zur Konvertieren der richtigen Byteanordnung

Syntax Bedeutung
uint32_t htonl(uint32_t); Konvertiert einen 32 Bit-Wert im host-byte-order zu einem 32 Bit-Wert im network-byte-order
uint16_t htons(uint16_t); Konvertiert einen 16 Bit-Wert im host-byte-order zu einem 16 Bit-Wert im network-byte-order
uint32_t ntohl(uint32_t); Konvertiert einen 32 Bit-Wert im network-byte-order zu einem 32 Bit-Wert im host-byte-order
uint16_t ntohs(uint16_t); Konvertiert einen 32 Bit-Wert im network-byte-order zu einem 32 Bit-Wert im host-byte-order


Rheinwerk Computing

B.13.3 Abfragen von Netzwerknummern und Internetadressen  downtop

Zur Verwendung der folgenden Funktionen sind folgende Headerdateien nötig:

#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>

Des Weiteren wird die Struktur in_addr verwendet, welche sich auch in der Headerdatei sockaddr_in wieder findet:

struct sockaddr_in {
  /* Adressfamilie normalerweise AF_INET  */
  short int          sin_family;
  /* Port der Verbindung                  */
  unsigned short int sin_port;
  /* Adresse zu der Verbunden werden soll */
  struct in_addr     sin_addr;
  /* Fuelldaten um auf 14 Bytes zu kommen */
  unsigned char      sin_zero[8]; 
};
struct in_addr{
     unsigned long int sin_addr;
}

Tabelle B.70    Funktionen zum Abfragen von Netzwerknummern und Internetadressen

Syntax Bedeutung
int inet_aton ( const char *name, struct in_addr *addr ); Konvertiert den String in der Punktierten Dezimaldarstellung (bspw. 127.0.0.1) in eine 32 Bit-Internetadresse.
uint32_t inet_network ( const char *name ); Extrahiert aus der als punktierten Dezimaldarstellung die Netzwerknummer.
char * inet_ntoa ( struct in_addr addr ); Konvertiert die übergebene 32 Bit-Adresse, die im network-byte-order vorliegen muss, in eine punktierte Dezimaldarstellung als String.
struct in_addr inet_makeaddr ( uint32_t net, uint32_t local ); Generiert aus dem lokalen Teil eines Rechners und einer Netzwerknummer eine numerische IP-Adresse.
uint32_t inet_lnaof ( struct in_addr addr ); Ermittelt die Adresse des lokalen Teils (bspw. 127.0.0.1 -> der lokale Teil = 0.0.0.1) des Rechners. Die Funktion gibt diesen Wert in Form eines 32 Bit-Wertes im host-byte-order zurück.
uint32_t inet_netof ( struct in_addr addr ); Konvertiert eine numerische 32 –Bit-Darstellung der IP-Adresse, die als Parameter angegeben wird, in eine Netzwerknummer, die im host-byte-order zurückgegeben wird
int inet_pton ( int af, const char *cp, void *buf ); Wie inet_aton() nur werden damit neben IPv4- auch IPv6-Adressen unterstützt.
const char * inet_ntop ( int af, const void *cp, char *buf, size_t len); Wie inet_ntoa() nur werden damit neben IPv4- auch IPv6-Adressen unterstützt.


Rheinwerk Computing

B.13.4 Hostnamen aus der Host-Datenbank ermitteln  downtop

Die Funktionen in diesem Abschnitt benötigen die folgenden Headerdateien:

#include <sys/socket.h>
#include <netdb.h>

Die Struktur hostent ist ein Datentyp, der einen Eintrag in der Host-Datenbank repräsentiert und folgende Mitglieder besitzt:

struct hostent { 
    char *  h_name; 
    char ** h_aliases; 
    short   h_addrtype; 
    short   h_length; 
    char ** h_addr_list; 
 };

Tabelle B.71    Funktionen, um auf die Host-Datenbank zuzugreifen

Syntax Bedeutung
struct hostent * gethostbyname ( const char *name ); Ermittelt die IP-Adresse (z. B. 192.0.34.72) passend zum angegebenen Internet-Host-Namen (z. B. www.example.com)
struct hostent * gethostbyaddr ( const char *addr, size_t length, int format ); Ermittelt den Internet-Host-Namen (z. B. www.example.com) passend zur angegebenen IP-Adresse (z. B. 192.0.34.72)
struct hostent * gethostbyname2( const char *name, int af ); Ermittelt die IP-Adresse (z. B. 192.0.34.72) passend zum angegebenen Internet-Host-Namen (z. B. www.example.com) – Der neu hinzugekommene Parameter af bezeichnet die gewünschte Adressfamilie AF_INET oder AF_INET6.


Rheinwerk Computing

B.13.5 Service-Datenbank  toptop

Die Funktionen in diesem Abschnitt benötigen die folgende Headerdatei:

#include <netdb.h>

Die Struktur servent ist ein Datentyp, der einen Eintrag in der Service-Datenbank repräsentiert und folgende Mitglieder besitzt:

struct    servent {
          char *s_name;       /* official name of service */
          char **s_aliases;   /* alias list               */
          int  s_port;        /* port service resides at  */
          char *s_proto;      /* protocol to use          */
      };

Tabelle B.72    Funktionen zum Zugriff auf die Service-Datenbank

Syntax Bedeutung
struct servent * getservbyname ( const char *name, const char *proto ); Ermittelt einen Port-Wert passend zu einem Internet-Dienst und Protokoll.
struct servent * getservbyport ( int port, const char *proto ); Ermittelt einen Internet-Dienst passend zu einem Port und Protokoll.

 << zurück
  
  Zum Rheinwerk-Shop
Neuauflage: Linux-UNIX-Programmierung
Neuauflage:
Linux-UNIX-
Programmierung

bestellen
 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: Linux-Server






 Linux-Server


Zum Rheinwerk-Shop: Das Komplettpaket LPIC-1 & LPIC-2






 Das Komplettpaket
 LPIC-1 & LPIC-2


Zum Rheinwerk-Shop: Linux-Hochverfügbarkeit






 Linux-
 Hochverfügbarkeit


Zum Rheinwerk-Shop: Shell-Programmierung






 Shell-
 Programmierung


Zum Rheinwerk-Shop: Linux Handbuch






 Linux Handbuch


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
Info





Copyright © Rheinwerk Verlag GmbH 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern