SUCHE MIT Google
Web virtualuniversity.ch
HOME DIDAKTIK ECDL ELEKTRONIK GUIDES HR MANAGEMENT MATHEMATIK SOFTWARE TELEKOM
DIENSTE
Anmeldung
Newsletter abonnieren
Sag's einem Freund!
VirtualUniversity als Startseite
Zu den Favoriten hinzufügen
Feedback Formular
e-Learning für Lehrer
Spenden
Autoren login
KURSE SUCHEN
Kurse veröffentlichen

Suche nach Datum:

Suche mit Schlüsselwort:

Suche nach Land:

Suche nach Kategorie:
PARTNER
ausbildung24.ch - Ausbildungsportal, Seminare, Kursen... 

 
HTMLopen.de - Alles was ein Webmaster braucht

 
PCopen.de - PC LAN Netze und Netzwerke - alles was ein IT Profi und Systemtechnicker braucht

TELEKOM

Die Socket-Netzwerkschnittstelle

Anfang der 80er Jahre wurde mit 4.2BSD in UNIX-Systemen die sogenannte "Socket"-Schnittstellefür die Kommunikation zwischen Prozessen eingeführt. Ein "Socket" ist dabei der Name für einen Endpunkt einer Kommunikationsverbindung. Seine Schnittstelle ist im wesentlichen konzipiert für:
  • verbindungsorientierte Kommunikation, aufsetzend auf TCP (SOCK_STREAM)
  • verbindungslose Kommunikation, aufsetzend auf UDP (SOCK_DGRAM)
  • direkten Zugriff auf die IP-Schicht (SOCK_RAW)
  • Kommunikation zwischen lokalen Prozessen (AF_UNIX)
  • Kommunikation zwischen im TCP/IP-Netz verteilten Prozessen (AF_INET)
  • Kommunikation für andere Protokoll- und Adressierungsfamilien
Dabei gibt es normalerweise ein Programm, das Anfragen von anderen Programmenentgegennimmt und sie beantwortet (ein sog. Server-Socket) und beliebigviele andere Programme, die ihre Anfragen an das Server-Socket schickenund mit den Antworten weiterarbeiten (die sog. Client-Sockets). Das ganzeSystem ist auch bekannt als Client-Server-Programmierung.Ein sehr typisches Beispiel sind Webserver: der Webserverwartet auf Anfragen von Browsern (oder User Agents o.ä.) und gibtWebseiten zurück. Die Browser arbeiten dann mit diesen Webseiten weiter,indem sie sie anzeigen und Operationen darauf erlauben (Anzeigen des Quelltextesetc.).

Die Socket-Schnittstelle ist zwar von keiner Institution genormt, stellt aber denIndustriestandard dar. Wichtige Gründe sind u.a.:

  • leicht verständliches Konzept
  • leicht zu handhaben und zu programmieren
  • fügt sich harmonisch in die UNIX-Welt ein
  • verfügbar für viele Systeme, z.B. die Windows Sockets, WinSock von Microsoft und anderen Firmen aus der PC-Welt definiert und kompatibel zu den UNIX-sockets.

Um mit einem bestimmten Dienst (Programm) auf einem anderen Rechner zu kommunizieren, reicht es allerdings nicht, einfach den anderen Rechner als solchen anzusprechen. Es ist vielmehr jedes Server-Programm auf einer bestimmten Port-Nummer zu erreichen. Jeder Client muß dem entfernten Rechner diese Port-Nummer mitteilen, damit dieser die Anfrage dem richtigen Programm zuleiten kann.

Die Netz-Ein- und Ausgabe wurde an die Datei-Ein- und Ausgabe angelehnt und etliche Ein- und Ausgabe-Systemaufrufe lassen sich auf Dateien und Sockets anwenden. Es gibt jedoch einige Unterschiede:

  • Die typische Client-Server-Beziehung ist unsymmetrisch. Zur Einrichtung einer Netzverbindung muß ein Programm seine Rolle kennen (Client oder Server).
  • Eine Netzverbindung kann verbindungsorientiert oder verbindungslos sein. Der erste Fall ähnelt einer Datei-E/A, der zweite Fall kennt kein "open" oder dergleichen.
  • Namen spielen bei Netzverbindungen eine größere Rolle. So kann ein Kindprozeß einen vom Elternprozeß übergebenen Dateideskriptor verwenden, ohne den Dateinamen zu kennen.
  • Es gibt mehr Parameter zur Spezifizierung einer Netzverbindung als bei der Date-E/A. Eine Verbindung wird durch fünf Parameter beschrieben:
    1. Protokoll
    2. lokale Adresse
    3. lokaler Prozeß
    4. ferne Adresse
    5. ferner Prozeß
  • Das Netz-Interface muß mehrere Kommunikationsprotokolle unterstützen und daher allgemeingütiger gehalten werden.

Verbindungsorientierte und verbindungslose Kommunikation

  • Die "verbindungsorientierte Kommunikation" geht davon aus, daß vor dem eigentlichen Datentransfer vom Client-Prozess eine logische Verbindung aufgebaut wird, über die dann in der Folge beliebig viele Datenpakete hin und her geschickt werden können - so lange bis einer der beiden Partner die Verbindung wieder abbricht ("hangup"). Bei dieser Art der Kommunikation wird Empfänger- und Absenderadresse nur beim Verbindungsaufbau angegeben - danach erfolgt die Kommunikation über Verbindungsnummern, die vom Betriebssystem zugeteilt werden. Die Telefonie funktioniert nach diesem Prinzip.
    Diese Form der Kommunikation eignet sich besser für Anwendungen, bei denen große Datenmengen übertragen werden. Der Verbindungsaufbau dauert zwar etwas, die eigentlichen Daten werden allerdings vollständig und in der richtigen Reihenfolge von der Quelle zum Ziel übermittelt.
  • Bei der "verbindungslosen Kommunikation" gibt es - wie der Name sagt - keine bestehende Verbindung zwischen den Partnern. Die Datenpakete werden einzeln mit den vollständigen Adressangaben versehen und auf den Weg gebracht. Im täglichen Leben entspricht dies der Kommunikation mittels Briefen.
    Bei diesem Modell - man spricht dabei auch von "Datagrammen" - wird vom Betriebssystem die korrekte Reihenfolge der einzelnen Datenpakete nicht garantiert. Es ist noch nicht mal gewährleistet, daß ein Paket überhaupt ankommt. Da jedoch der zeitaufwendige Verbindungsaufbau entfällt, ist es in Fällen, bei denen es mehr auf Schnelligkeit als auf Sicherheit ankommt, oft die bessere Wahl. Eventuell nötige Reihenfolge-Überprüfungen bzw. Zeitüberwachngen müssen dann aber vom Anwendungsprozess selbst vorgenommen werden.

Sockets

Zur Kommunikation zwischen Prozessen, die auch auf verschiedenen Rechnern ablaufen können, wurde mit den Sockets im BSD-Unix ein leistungsfähiger Mechanismus der Datenübertragung definiert. Sockets sind heute Grundlage der meisten höheren Datenübertragungsprotokolle und in fast allen Betriebssystemen realisiert. Sie stellen die Schnittstelle zwischen Anwendungsprogramm und den Betriebssystemroutinen zur Datenkommunikation dar. Dabei besteht der Vorteil für den Benutzer darin, daß einem Socket ein Dateideskriptor zugeordnet wird, über den das Anwendungsprogramm fast genauso kommunizieren kann, wie über Pipes oder normale Dateien. Im Gegensatz zu einer Pipe, die grundsätzlich nur in einer Richtung betrieben werden kann, ist ein Socket-Deskriptor jedoch bidirektional - wie eine zum Lesen und Schreiben geöffnete Datei. Sockets sind, wie die Client-Server-Beziehung, unsymmetrisch: Einer der beiden beteiligten Prozesse ist "Server", der andere "Client". Der Server (Diensterbringer) wartet darauf, daß irgendein Client (Kunde) mit ihm Kontakt aufnehmen möchte. Der Client ist der aktive Part und veranlasst den Beginn der Kommunikation.

Über Sockets kann der Datenaustausch auf zweierlei Art erfolgen:

  1. Datenströme (Streams): Zwischen Client und Server wird eine Verbindung aufgebaut, die einzelnen Datenpakete werden gesichert und in korrekter Reihenfolge übertragen und zum Schluß wird die Verbindung wieder abgebaut. Dies entspricht dem Zyklus "open" - "read"/"write" - "close" bei einer normalen Datei. Bei einer Verbindung über IP wird dafür TCP benutzt.
  2. Einzelpakete (Datagrams): Datagramme werden gleichsam als "Pakete" mit Absender- und Empfängeradresse verschickt. Das entsprechende Internet-Protokoll heißt UDP. Es wird keine Verbindung zwischen den beiden Prozessen aufgebaut, weshalb UDP wesentlich schneller ist. Allerdings gibt es keine Garantie für das Ankommen des Paketes bei der Gegenseite und keine Gewähr für die Einhaltung der richtigen Reihenfolge.
Sockets sind noch über verschiedenen "Domänen" definiert: Es gibt neben der "Internet-Domäne" noch weitere Domänen, z. B.die "Unix-Domäne" für die Kommunikation zwischen reinen Unix-Prozessen. Thema der Vorlesung ist aber ausschließlich die Internet-Domäne.

Die Systemaufrufe im Überblick

Einige wichtige Socket-Primitive bzw. -Systemcalls sind:
  • Erstellen eines Socket:
    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) zum Eröffnen einer verbindungsorientierten Kommunikation im Internet
  • Verbindungsaufbau:
    bind(s, address, addresslength) zum Verbinden des Sockets mit der lokalen Endpunktadresse
    cs = connect(s, address, addresslength) zum Verbindungsaufbau über einen virtuellen Kanal zum entfernten Prozess
  • Kommunikation:
    nwrite = write(s, buffer, nbytes) (bzw. send(...)) und
    nread = read(s, buffer, maxbytes) (bzw. recv(...) zum Schreiben bzw. Lesen auf/vom virtuellen Kanal
  • Verbindungsabbau:
    close(s)

Die folgende Tabelle gibt einen Überblick über die wichtigsten Socket-Systemcalls in Client- und Serverprogrammen:

Phase Client Server
Endpunkt erzeugen socket() socket()
Binden einer Adresse bind() bind()
Verbindung aufbauen connect()  
Warteschlange festlegen   listen()
Warten auf Verbindung   accept()
Daten senden write()
send()
sendto()
sendmsg()
write()
send()
sendto()
sendmsg()
Daten empfangen read()
recv()
recvfrom()
recvmsg()
read()
recv()
recvfrom()
recvmsg()
Verbindung schließen shutdown() shutdown()
Endpunkt abbauen close() close()
Ereignisse annehmen select() select()
Verschiedenes getpeername()
getsockname()
getsockopt()
setsockopt()
getpeername()
getsockname()
getsockopt()
setsockopt()

Für die Kommunikation bei verbindungslosen, d.h. UDP-basierten Socketanwendungen sind die speziellen send()- und receive()-Systemcalls empfehlenswert, während bei TCP-Verbindugen daneben die Standard-Systemcalls read() und write() einsetzbar sind.

Eine TCP/IP-Verbindung ist, wie wir gesehen haben, durch eine Client-Server-Architektur geprägt und damit asymetrisch. Vor der Programmierung muß die Verbindung stehen. Das betrifft einmal die Verbindung zwischen den Rechnern, als auch jene zwischen den Prozessen. Die Adressierung der Rechner erfolgt per Hostname, der vom System auf die IP-Nummer umgesetzt wird.

Vom Client aus muß nicht nur der richtige Rechner, sondern auch der richtige Serverprozeß angesprochen werden können. Dazu bindet sich der Serverprozeß an einen festen Port, über den er erreichbar ist. Damit die Nummer des Ports mit einem Namen versehen werden kann, verwendet man die Datei /etc/services. Im Programm wird die Servicenummer durch den Aufruf der Systemfunktion getservbyname() bestimmt.

Der Client braucht keinen festen Port. Er erbittet sich auf der lokalen Maschine eine freie Nummer und ruft damit den Port des Servers. Der Server erfährt die Nummer des Clients aus der Anfrage und kann ihm unter diesem Port antworten. Das Szenario zwischen Server und Client sieht wie folgt aus:

Betrachten wir beispielhaft einmal das Listing eines ganz einfachen Servers in der Programmiersprache C. Die einzelnen Systemaufrufe werden weiter unten genauer behandelt, das Listing soll zunächst nur einen Überblick des Ablaufs geben:

                                       #include <sys/types.h>
                                       #include <sys/socket.h>
                                       #include <netinet/in.h>
                                       #include <netinet/tcp.h>
                                       #include <netdb.h>
                                       
                                       #define MAXPUF 1023
                                       
                                       main()
                                         {
                                         int MySocket, ForeignSocket;
                                         struct sockaddr_in AdrMySock, AdrPartnerSocket;
                                         struct servent *Service;
                                         int AdrLen;
                                       
                                         char Puffer[MAXPUF];
                                         int MsgLen;
                                       
                                         /* Socket einrichten */
                                         MySocket = socket(AF_INET, SOCK_STREAM, 0);
                                       
                                         /* Socket an Port-Nummer binden */
                                         AdrMySock.sin_family = AF_INET;         /* Internet-Protokolle */
                                         AdrMySock.sin_addr.s_addr = INADDR_ANY; /* akzept. jeden Client-Host */
                                         Service = getservbyname("echo","tcp");   /* bestimme Port */
                                         AdrMySock.sin_port = Service->s_port;   /* (Get Service by Name) */
                                         bind(MySocket, &AdrMySock, sizeof(AdrMySock));
                                       
                                         /* Empfangsbereitschaft signalisieren und warten */
                                         listen(MySocket, 5);
                                       
                                         for (;;) /* forever */ 
                                           {
                                           /* Verbindungswunsch vom Client annehmen */
                                           ForeignSocket = accept(MySocket, &AdrPartnerSocket, &AdrLen);
                                           /* Datenaustausch zwischen Server und Client */
                                           MsgLen = recv(ForeignSocket, Puffer, MAXPUF, 0); /* String empfangen */
                                           send(ForeignSocket, Puffer, MsgLen, 0); /* und zuruecksenden */
                                           /* Verbindung beenden und wieder auf Client warten */
                                           close(ForeignSocket);
                                           }
                                         }
                                       
Dieser Server bearbeitet jede Anfrage, die über den Port "echo" an ihn gestellt wird. Nach jeder Anfrage wird die Verbindung wieder gelöst und ein anderer Client kann anfragen. Ein solcher Server dürfte auf jedem Betriebssystem arbeiten können, das TCP/IP unterstützt, selbst wenn es kein Multitasking beherrscht.

Es gibt zwei Variablen pro Socket. Die eine ist wie bei Dateizugriffen ein einfaches Handle (MySocket), die andere hält die Adresse der Verbindung (AdrSock), also die IP-Nummer des Rechners und die Nummer des verwendeten Ports. Der Server erlaubt Verbindungen von jedem Rechner aus, weil die Konstante INADDR_ANY benutzt wird.

Der zugehörige Client gibt dagegen die Adresse des anzusprechenden Servers an. Das Programm sieht wie folgt aus:

                                       #include <sys/types.h>
                                       #include <sys/socket.h>
                                       #include <netinet/in.h>
                                       #include <netinet/tcp.h>
                                       #include <netdb.h>
                                       
                                       #define MAXPUF 1023
                                       
                                       main()
                                         {
                                         int MySocket;               /* Socket-Handle */
                                         struct sockaddr_in AdrSock; /* Socketstruktur */
                                         int len;                    /* Die Laenge der Socketstruktur */
                                       
                                         struct hostent *RechnerID;  /* ferner Rechner */
                                         struct servent *Service;    /* Dienst auf dem fernen Rechner */
                                       
                                         char Puffer[MAXPUF] = "Wir erschrecken zu guten Zwecken!";
                                       
                                         MySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
                                       
                                         /* Bestimme den Zielrechner */
                                         RechnerID = gethostbyname("server");
                                         bcopy(RechnerID->h_addr,&AdrSock.sin_addr,RechnerID->h_length);
                                       
                                         /* Bestimme den Port */
                                         Service = getservbyname("echo","tcp");
                                         AdrSock.sin_port = Service->s_port;
                                       
                                         connect(MySocket, (struct sockaddr *)&AdrSock, sizeof(AdrSock));
                                         send(MySocket, Puffer, MAXPUF, 0);  /* String senden */
                                         recv(MySocket, Puffer, MAXPUF, 0);  /* und wieder empfangen */
                                         printf("%s\n", Puffer);             /* ausgeben */
                                         close(MySocket);
                                         }
                                       
Die recv-Funktion liefert als Rückgabewert die Größe des versandten Speicherbereichs (max. 1 KByte, siehe unten).

Grundsätzlich liefern fast alle Netz-Funktionen bei Fehlern den Wert 0 zurück. In den obigen Beispiel-Listing fehlt jegliche Fehlerbehandlung, damit das Prinzip übersichtlich dargestellt werden kann. Im "richtigen" Programm ist eine umfassende Fehlerbehandlung unumgänglich.

Das Server-Programm hat noch einen Nachteil. Nach dem Start des Servers ist die Konsole oder das Shell-Fenster für weitere Zwecke blockiert. Auch fehlt eine korrekte Möglichkeit, den Server zu beenden. Bei einem Abbruch des Programms wird es dem Betriebssystem überlassen, den Socket zu schließen. Zweckmässigerweise wird vom Programm ein Dämon erzeugt, der per fork-Aufruf in den Hintergrund gestellt.

DIPLOMARBEITEN UND BÜCHER

Diplomarbeiten zum Runterladen:

Suche im Katalog:
Architektur / Raumplanung
Betriebswirtschaft - Funktional
Erziehungswissenschaften
Geowissenschaften
Geschichtswissenschaften
Informatik
Kulturwissenschaften
Medien- und Kommunikationswissenschaften
Medizin
Psychologie
Physik
Rechtswissenschaft
Soziale Arbeit
Sozialwissenschaften


JOBS
HOME | E-LEARNING | SITEMAP | LOGIN AUTOREN | SUPPORT | FAQ | KONTAKT | IMPRESSUM
Virtual University in: Italiano - Français - English - Español
VirtualUniversity, WEB-SET Interactive GmbH, www.web-set.com, 6301 Zug

Partner:   Seminare7.de - PCopen.de - HTMLopen.de - WEB-SET.com - YesMMS.com - Ausbildung24.ch - Manager24.ch - Job und Karriere