Zur Kommunikation zwischen Prozessen, die auch auf verschiedenen Rechnern ablaufen können, wurde mit den Sockets 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 normale Dateien. 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.

Das Szenario zwischen Server und Client sieht bei Datenströmen wie folgt aus:

VNS Praxis - 04 - Sockets

Server Beispiel:

#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 */
  memset(&AdrMySock, 0, sizeof (AdrMySock));
  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);
    }
  }

Client Beispiel:

#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);
  memset(&AdrSock, 0, sizeof (AdrSock));

  /* Bestimme den Zielrechner */
  RechnerID = gethostbyname("server");
  bcopy(RechnerID->h_addr,&AdrSock.sin_addr.s_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);
  }

Quelle: http://www.netzmafia.de/skripten/inetprog/inetprog1.html