Start Programmierung Python Python in einfachen Beispielen : Socketprogrammierung
20 | 05 | 2012
Python in einfachen Beispielen : Socketprogrammierung
Geschrieben von: Joerg   
Freitag, den 13. Mai 2011 um 18:40 Uhr

Was ist ein Socket?

Ein Socket ist ein Endpunkt einer Verbindung in einem Kommunikationsnetzwerk. Bei einer Netzwerkkommunikation zwischen zwei Rechnern benötigen wir immer zwei Sockets. Da in einem Netzwerk Rechner mit unterschiedlichen Betriebssystemen und unterschiedlicher Hardwareausstattung zusammenarbeiten, müssen klare Schnittstellen der Kommunikation definiert werden. Das Modul socket in Python bietet die Funktionen an, um eine Kommunikation durchzuführen.

Ein Socket benötigt maximal drei Informationen:

  • 1. die Adresse des Rechners bestehend aus IP und Port(nummer).
  • 2. das Protokoll,
  • 3. den Prozess, der auf dem Rechner ausgelöst werden muss.




Was ist eine IP-Adresse ( IPv4 IPv6), was ist ein Port?


Jeder Rechner im Netz hat eine eindeutig zum Zeitpunkt der Kommunikation zugeordnete IP-Adresse (32-Bit (IPv4) bzw. 128-Bit (IPv6)). Hinzu kommt eine 16-Bit-Integer-Zahl, der sogenannte Port. Für bestimmte Kommunikationsarten gibt es voreingestellte Ports. Beispielsweise gilt für die Webseitenübermittlung der Port 80 als Standardport, für den eMail-Versand (SMTP) gibt es den Port 25 usw. Dann muss deutlich werden, auf welche Weise die Daten übertragen werden sollen. Es muss also das Übertragungsprotokoll angegeben werden. Sind diese Daten festgelegt, müssen auf den Rechnern die geigneten Prozesse ausgelöst werden. In der Regel sind diese Prozesse auf den jeweiligen Rechnern bereits durch IP-Adresse, Port und Protokoll eindeutig festgelegt.

(s.a. http://www.tu-ilmenau.de/fakia/fileadmin/template/startIA/telematik/lehre/praktikum/socket-api.pdf, 10.05.2011; http://www.c-worker.ch/tuts/wstut_op.php, 10.05.2011)

Was ist ein Client, was ein Server?

Bei der Kommunikation gibt es einen aktiven Teil (Client) und einen passiven Teil (Server). Der Client muss die Adresse des Servers kennen. Nicht immer können Client und Server genau voneinander unterschieden werden. Handelt es sich um ein verbindungsorientiertes Protokoll (beispielsweise TCP), so nimmt der Client mit Hilfe des Befehls connect() die Beziehung zu dem Server auf. Der Server sieht nach, ob die Zahl der zulässigen Verbindungen (Unterprogramm listen()) noch nicht erreicht wurde, falls nicht, wird auf dem Server das Unterprogramm accept() aufgerufen. accept() gibt als Rückgabewert einen Socket zurück, der dann die eigentliche Verbindung auf dem Server mit dem ClientSocket bildet. Der Server muss den Port des Clients nicht kennen, das Betriebsystem, unter dem der Server läuft, kann als Port des Clients eine beliebige 16-Bit IntegerZahl dem Client zuordnen, der Port der vom Server für die Verbindung serverseitig zur Verfügung gestellt wird, muss mit bind() mit der IP-Adresse des Servers verknüpft werden.
(s.a. http://www.codeplanet.eu/tutorials/csharp/4-tcp-ip-socket-programmierung-in-csharp.html, 10.05.2011)

Was ist IP, TCP oder UDP?

Das grundlegende Protokoll einer Netzwerkverbindung ist das Internet-Protokoll (IP). Zu übertragende Daten werden in kleine Päckchen aufgeteilt, die dann auf unterschiedlichen Wegen im Netz dem Zielrechner zugestellt werden können. Jedes Paket besteht aus einem Header, der die Adressen, Protokollname u.ä. enthält und einem Datenteil, der Datenteil enthält häufig ein weiteres Protokoll (bspw. TCP, UDP ...). Auf dem Zielrechner werden dann dem Protokoll gemäß diese Päckchen wieder zusammengestellt. TCP (TRANSMISSION CONTROL PROTOCOL) überprüft die Datenpakete auf Vollständigkeit und Datenfehler. Bei Bedarf wird dann ein fehlerhaftes oder fehlendes Paket erneut angefordert. In diesem Fall wird also die Kommunikation komfortabler, aber auch langsamer.

UDP (USER DATAGRAM PROTOCOL) arbeitet mit geringeren Anforderungen als das TCP. Dadurch wird ein geringerer Datenverkehr erzeugt. UDP führt damit zu einem schnelleren Datenverkehr. Allerdings fehlt eine Endkontrolle der Übertragung. UDP zählt zu den sogenannten verbindungslosen Übertragungsdiensten. Auch unter UDP können wir den Befehl connect() aufrufen, allerdings wird hierbei keine Verbindung aufgebaut. Damit trotzdem ein Datenfluss möglich ist, gibt es in einem UDP-Server die Funktion recvfrom(). Als Werte übergibt die Funktion die Adresse (IP-Adresse, Port) und die gesendeten Daten. Der Server wartet nach Aufruf der Funktion auf ein eingehendes Datenpaket, welches zur eigenen Adresse passt (IP-Adresse und Port), entsprechend kennt der UDP-Client den Befehl sendto(). Mit dem Befehl wird Ziel-IP, Port und die Nachricht übertragen.

Die IP-Adresse ist so etwas wie die Anschrift einer Firma. Durch die Angabe des Ports wird die Sendung einer bestimmten Abteilung der Firma zugestellt. Wird das Protokoll TCP verwendet, so entspricht dies einem Einschreibebrief mit Rückantwort, der direkt vom Sachbearbeiter bearbeitet wird. Der Client erfährt, ob das Päckchen korrekt angekommen ist, falls nicht, schickt er das Päckchen erneut ab. Jedem Client wird durch den Server bei einer TCP-Verbindung genau ein Socket zugewiesen. UDP hat diese Absicherung nicht. Das Päckchen wird zugestellt und der Client weiß nicht, ob das Päckchen wirklich angekommen ist. Kommt von einem weiteren Client ein neues Päckchen an, so wird derselbe Socket genutzt.

(s.a. http://de.wikipedia.org/wiki/Netzwerkprotokoll, 10.05.2011; http://de.wikipedia.org/wiki/IP-Header, 10.05.2011 ; http://www.c-worker.ch/tuts/wstut_op.php , 10.05.2011 )



Was sind Unicast, Broadcast, Multicast und Anycast?



Es handelt sich hierbei um Socketoptionen.

Unicast
ist die Option, die immer bei TCP-Verbindungen wichtig ist. Unicast liefert eine Nachricht an einen genau festgelegten Kommunikationsknoten.

Broadcast schickt diese Nachricht an alle Knoten eines Netzwerkes.

Multicast liefert die Nachricht nur an Knoten, die diese Nachricht nachfragen. Broadcast bzw. Multicast kann von UDP-Sockets und nicht von TCP-Sockets genutzt werden.

Anycast liefert die Nachricht  an jeden Knoten innerhalb einer Gruppe von Knoten.

s.a. http://www.codeplanet.eu/tutorials/csharp/4-tcp-ip-socket-programmierung-in-csharp.html?start=3; 15.05.2011

 

 

Beispiel für eine UDP-Kommunikation (Python 2.7)

 

 

UDP-Client
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import socket
Ziel='127.0.0.1'
Port=5005
# Die Konstante AF_INET steht für Adressfamilie Internet.
# Die Konstante SOCK_DGRAM steht für das UDP-Protokoll.
# Dies sind optionale Eingaben für eine Socket-Instanz.
# Voreingestellt ist AF_INET und als Protokoll SockStream, dies steht für
# ein TPC-socket
 
s_udp_sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
 
 
print '##########DIES IST DER Sender########'
print 'Neue Verbindung:'
print 'Ziel=',Ziel
print 'Port=',Port
 
 
def sende(Nachricht):
print "Nachricht:", Nachricht
s_udp_sock.sendto( Nachricht, (Ziel,Port) )
 
# Mit sende('Hallo') schicken wir die Nachricht 'Hallo' an den durch (Ziel,Port)
# spezifizierten Kommunikationsknoten. In diesem Fall ist es der eigene Rechner.
 

Der Server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import socket
Quelle='127.0.0.1' # Adresse des eigenen Rechners
Port=5005
 
e_udp_sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM ) #s.o.
e_udp_sock.bind( (Quelle,Port) ) #Im IP-Adresse und Port werden
# durch bind miteinander verknüpft.
print '########Dies ist der Empfänger########'
print 'Neue Verbindung:'
print 'Quelle',Quelle
print 'Port=',Port
 
 
 
 
def empfange():
 
 
 
while 1: # Endlosschleife
data, addr = e_udp_sock.recvfrom( 1024 )# Puffer-Größe ist 1024 Bytes.
# Die Puffergröße muss immer eine Potenz
# von 2 sein
print "empfangene Nachricht:", data
print "Clientadresse:", addr # Adresse besteht aus IP und Port
 
 
empfange() #Programm wartet in einer Endlosschleife auf eingehende Nachrichten, Herkunftsort ist egal.
 

 

Hinweis:

Es ist es unerheblich, woher die Nachricht kommt (verbindungslose Kommunikation). Entscheidend für die Kommmunikation ist die Socketinstanz und die Funktion bind(). Durch bind() wird die UDP-Socketinstanz zu einem UDP-Server.

Wird die Funktion recvfrom() aufgerufen (s.o.), so kann hiermit auf Client-Nachrichten zugegriffen werden. Ist keine Nachricht vorhanden, wartet die Funktion auf die nächste eingehende Nachricht, erst dann wird das Programm fortgesetzt.

Tags: