Socket-Programmierung in Python: Ein Leitfaden für Anfänger

Aditya Raj 10 Oktober 2023
  1. So implementieren Sie die Socket-Programmierung in Python
  2. So erstellen Sie einen Server in der Socket-Programmierung in Python
  3. Socket-Programmierung mit dem UDP-Protokoll in Python
  4. Fazit
Socket-Programmierung in Python: Ein Leitfaden für Anfänger

Wenn wir ein Programm schreiben, müssen wir normalerweise nicht mit anderen Programmen oder Computern kommunizieren.

Wir müssen jedoch möglicherweise mit anderen Computern kommunizieren, um Messenger- oder andere Anwendungen mit Server-Client-Architektur zu erstellen. Um solche Anwendungen zu erstellen, können wir die Socket-Programmierung in Python verwenden.

Dieser Artikel behandelt die Grundlagen der Socket-Programmierung in Python. Wir werden auch separat eine einfache Messenger-Anwendung implementieren, die Socket-Programmierung mit TCP- und UDP-Protokollen verwendet.

Was sind Sockets in Python?

Wenn zwei Anwendungen oder Prozesse interagieren, verwenden sie einen bestimmten Kommunikationskanal. Sockets sind die Endpunkte oder Einstiegspunkte solcher Kommunikationskanäle.

Wir können Sockets verwenden, um einen Kommunikationskanal zwischen zwei Prozessen, innerhalb eines Prozesses oder zwischen Prozessen auf verschiedenen Maschinen herzustellen. Es gibt verschiedene Arten von Sockets wie TCP-Sockets, UDP-Sockets und UNIX-Domain-Sockets.

So implementieren Sie die Socket-Programmierung in Python

Python stellt uns das Modul socket zur Verfügung, um die Socket-Programmierung zu implementieren. Das Modul socket ist Teil der Standard-Python-Bibliothek und stellt alle Funktionen und Methoden bereit, mit deren Hilfe Sie Sockets in Python erstellen können.

Sie müssen das socket-Modul nicht explizit in Ihren Computer herunterladen, und Sie können es direkt in Ihr Programm importieren, indem Sie die import-Anweisung wie folgt verwenden.

import socket

Um die Socket-Programmierung zu implementieren, müssen wir zwei Prozesse erstellen, die über den Socket kommunizieren.

Eines der Programme arbeitet als Server und das andere als Client. Sowohl der Server als auch der Client haben unterschiedliche Funktionalitäten. Daher verwenden wir verschiedene Funktionen beim Erstellen von Server- und Clientprozessen.

Lassen Sie uns besprechen, wie Sie nacheinander einen Server- und einen Client-Prozess erstellen.

So erstellen Sie einen Server in der Socket-Programmierung in Python

Um einen Server zu erstellen, erstellen wir zuerst einen Socket. Dazu verwenden wir die Methode socket().

Erstellen Sie einen Socket: Die socket()-Methode

Die Syntax für die Methode socket() ist wie folgt.

socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, fileno=None)

Hier,

  • Der Parameter family stellt die Adressfamilie dar, zu der ein Socket gehört. Standardmäßig ist es AF_INET und erstellt einen Socket mit einer Internet Protocol Version 4 (IPv4)-Adresse. Sie können andere Adressfamilien wie AF_UNIX für die UNIX-Adresse und AF_INET6 für die Adresse des Internetprotokolls Version 6 (IPv6) verwenden.
  • Der Parameter type bezeichnet den Socket-Typ. Standardmäßig hat es den Wert SOCK_STREAM, was bedeutet, dass der Socket dem verbindungsorientierten TCP-Protokoll folgt. Sie können SOCK_DGRAM verwenden, um Datagramm-Sockets zu erstellen, die dem UDP-Protokoll folgen.
  • Der Parameter proto bezeichnet die Protokollnummer und ist normalerweise 0. Wenn Sie die Adressfamilie AF_CAN in der Parameterfamilie verwenden, sollte die Protokollnummer eine von CAN_RAW, CAN_BCM, CAN_ISOTP oder CAN_J1939 sein.
  • Der Parameter fileno enthält den Standardwert None. Wenn wir in fileno einen Dateideskriptor angeben, werden die Werte für die Parameter family, type und proto automatisch aus dem Dateideskriptor ermittelt.

Nachdem wir einen Socket erstellt haben, binden wir ihn mit der Methode bind() an eine Adresse und eine Portnummer.

Den Socket an eine Adresse binden: Die bind()-Methode

Mit der Funktion socket() wird die Methode bind() auf dem von uns erstellten Socket-Objekt aufgerufen.

Es nimmt ein Tupel, das die Adresse enthält, an die der Socket gebunden wird. Das Format der Adresse kann je nach gewählter Adressfamilie variieren. Wir erstellen einen Socket mit der Adressfamilie AF_INET. Daher enthält die Adresse den Hostnamen und die Portnummer.

Die Syntax für die Methode bind() ist wie folgt.

bind((hostname, port))

Sie können den Hostnamen explizit angeben. Wenn Sie den Server auf dem lokalen Rechner erstellen, können Sie den Hostnamen als localhost oder 127.0.0.1 angeben, den Standardwert für die localhost-Adresse.

Alternativ können Sie die Methode gethostname() verwenden, um den Hostnamen zu erhalten. Für den Parameter port können Sie jede Portnummer über 1024 und kleiner als 65535 verwenden.

Nachdem der Socket an eine Adresse gebunden wurde, hört der Server die Verbindungsanfragen des Clients ab. Dazu verwenden wir die Methode listen().

Verbindungen abhören: Die listen()-Methode

Die Syntax für die Methode listen() ist wie folgt.

listen(backlog)

Der Parameter backlog gibt hier die maximale Anzahl nicht akzeptierter Verbindungen an, die das System zulässt, bevor neue Verbindungen abgelehnt werden.

Nach Ausführung der listen()-Methode ist der Server bereit, Verbindungen anzunehmen.

Akzeptiere eine Verbindungsanfrage: Die accept()-Methode

Der Server läuft ständig in einer Endlosschleife und wartet auf Clientanforderungen, um eine Verbindung von einem Client zu akzeptieren. Sobald eine Client-Anfrage gefunden wird, akzeptiert der Server die Anfrage mit der accept()-Methode.

Die Methode accept() gibt ein Tupel (client, address) zurück. Hier stellt client ein neues Socket-Objekt dar, das wir zum Senden und Empfangen von Nachrichten verwenden. Die Adresse ist dort, wo der Client-Socket gebunden ist.

Kommunikation mit dem Client: Methoden send() und recv()

Nach dem Akzeptieren der Verbindung kann der Server mit dem Client kommunizieren.

Wir verwenden die Methode send(), um eine Nachricht an den Client zu senden. Die send()-Methode wird auf dem client-Objekt aufgerufen, das von der accept()-Methode zurückgegeben wird.

Wir verwenden die Methode recv(), um die Nachrichten zu empfangen. Die recv()-Methode akzeptiert, wenn sie auf dem client-Objekt aufgerufen wird, eine Zahl, die die maximale Anzahl von Bytes darstellt, die sie von der Verbindung lesen kann. Nach der Ausführung gibt es die von der Verbindung gelesenen Daten zurück.

Nachdem alle Vorgänge abgeschlossen sind, müssen wir die Verbindung schließen. Dazu rufen wir die close()-Methode auf dem client-Objekt auf, das von der accept()-Methode zurückgegeben wird.

Nachdem wir alle Methoden besprochen haben, die zum Erstellen eines Servers erforderlich sind, lassen Sie uns einen Serverprozess erstellen.

import socket

mySocket = socket.socket(
    family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, fileno=None
)
print("Socket created.")
hostname = "localhost"
portno = 9999
mySocket.bind((hostname, portno))
print("Socket bound to address {} and port number {}".format(hostname, portno))
mySocket.listen(5)
print("Listening for client.")
while True:
    client, client_addr = mySocket.accept()
    print("Connection established with client at address {}".format(client_addr))
    msg = client.recv(1024).decode()
    print("Message received from the client:")
    print(msg)
    print("Sending acknowledgment to the client.")
    msg_out = "Message received: {}. Thank you.".format(msg).encode()
    client.send(msg_out)
    print("Terminating the connection.")
    client.close()
    break

Nachdem wir nun einen Server erstellt haben, erstellen wir einen Client-Prozess, der mit dem Server kommuniziert.

So erstellen Sie einen Client in der Socket-Programmierung

Um einen Client zu erstellen, müssen wir zuerst einen Socket mit der Methode socket() erstellen, wie wir es beim Erstellen des Servers getan haben. Denken Sie daran, dass die für den Client-Socket definierten Protokolle die gleichen sein sollten wie für den Server-Socket. Andernfalls funktioniert das Programm nicht wie gewünscht.

Nachdem wir den Socket erstellt haben, müssen wir ihn mit dem Server verbinden. Dazu verwenden wir die Methode connect().

Mit dem Server verbinden: Die connect()-Methode

Die Syntax für die Methode connect() ist wie folgt.

connect((host, port))

Dabei bezeichnet der Parameter host die Adresse des Servers. Der Parameter port bezeichnet die Portnummer, unter der der Server-Socket erstellt wird. Sie sollten die gleichen Werte als Eingabe für die Host- und Portparameter angeben, die Sie beim Erstellen des Servers für die Methode bind() angegeben haben.

Kommunikation mit dem Server

Nachdem Sie sich mit dem Server verbunden haben, können Sie mit den Methoden send() und recv() mit dem Server kommunizieren. Schließlich würde es helfen, die Verbindung von der Client-Seite mit der Methode close() zu schließen.

Das Folgende ist das Client-Programm, das wir verwenden werden, um einen Client-Prozess zu erstellen.

import socket

mySocket = socket.socket(
    family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, fileno=None
)
print("Socket created.")
hostname = "localhost"
portno = 9999
mySocket.connect((hostname, portno))
print("Connection established with the server.")
msg = "Hi I am a TCP client created by Aditya."
print("Sending msg to the server:", msg)
mySocket.send(msg.encode())
msg_in = mySocket.recv(1024).decode()
print("Acknowledgment received from the server:")
print(msg_in)
print("Terminating the Connection.")
mySocket.close()

Nachdem wir den Server und den Client erstellt haben, lassen Sie uns nun die Programme ausführen. Denken Sie daran, dass Sie sowohl das Clientprogramm als auch das Serverprogramm gleichzeitig ausführen sollten, damit beide Prozesse gleichzeitig aktiv sein und miteinander kommunizieren können.

Die Ausgabe im Terminal mit dem Serverprogramm sieht dann so aus:

Socket created.
Socket bound to address localhost and port number 9999
Listening for client.
Connection established with client at address ('127.0.0.1', 37958)
Message received from the client:
Hi I am a TCP client created by Aditya.
Sending acknowledgment to the client.
Terminating the connection.

Die Ausgabe im Terminal mit dem Client-Programm sieht so aus:

Socket created.
Connection established with the server.
Sending msg to the server: Hi I am a TCP client created by Aditya.
Acknowledgment received from the server:
Message received: Hi I am a TCP client created by Aditya.. Thank you.
Terminating the Connection.

Socket-Programmierung mit dem UDP-Protokoll in Python

In den vorherigen Abschnitten haben wir Sockets erstellt, die dem TCP-Protokoll in der Verbindung folgen. Beim TCP-Protokoll wird die Verbindung zwischen dem Client und dem Server während der gesamten Kommunikation aufrechterhalten.

Es gibt jedoch viele Situationen, in denen wir aufgrund von Ressourcenbeschränkungen keine stabile Verbindung zwischen dem Client und dem Server aufrechterhalten können. Daher brauchen wir ein Kommunikationsprotokoll, das keine stabile Verbindung erfordert. Dazu verwenden wir das UDP-Protokoll.

So erstellen Sie einen Server mit UDP-Protokoll in Python

Um eine Verbindung mit dem UDP-Protokoll herzustellen, müssen wir bei der Implementierung des Servers die folgenden Schritte ausführen.

  • Geben Sie SOCK_DGRAM in der Eingabe für den Typparameter an, während Sie den Server-Socket mit der socket()-Methode erstellen.
  • Binden Sie den Socket mit der Methode bind() an eine Adresse und eine Portnummer.
  • Da wir keine Verbindung mit dem Client herstellen müssen, verwenden wir die Methoden listen() und accept() nicht, um die Verbindung herzustellen. Wir können direkt mit dem Kunden kommunizieren.
  • Um eine Nachricht im UDP-Protokoll zu empfangen, verwenden wir die Methode recvfrom(). Es nimmt die Anzahl der zu lesenden Bytes als Eingabeargument und gibt ein Tupel zurück, das die Daten und die Adresse enthält, von der die Daten empfangen wurden.
  • Um eine Nachricht im UDP-Protokoll zu senden, verwenden wir die Methode sendto(). Die Methode sendto() nimmt die Daten als erstes Eingabeargument und ein Tupel, das den Hostnamen und die Portnummer enthält, als Adresse des Sockets, an den die Daten gesendet werden.
  • Nach der Kommunikation muss der Socket mit der Methode close() geschlossen werden.

Mit dem folgenden Python-Programm können Sie einen Serverprozess implementieren, der mit dem UDP-Protokoll kommuniziert.

import socket

mySocket = socket.socket(
    family=socket.AF_INET, type=socket.SOCK_DGRAM, proto=0, fileno=None
)
print("Socket created.")
hostname = "localhost"
portno = 9999
mySocket.bind((hostname, portno))
print("Socket bound to address {} and port number {}".format(hostname, portno))
while True:
    msg, client_addr = mySocket.recvfrom(1024)
    print("Message received from the client:")
    print(msg.decode())
    print("Sending acknowledgment to the client.")
    msg_out = "Message received: {}. Thank you.".format(msg).encode()
    mySocket.sendto(msg_out, client_addr)
    mySocket.close()
    break

So erstellen Sie einen Client mit UDP-Protokoll in Python

Um einen Client-Prozess zu erstellen, der dem UDP-Protokoll folgt, müssen wir den Socket erstellen, indem wir SOCK_DGRAM in der Eingabe für den Typparameter angeben, während wir den Server-Socket mit der socket()-Methode erstellen. Wir müssen hier nicht die Methode connect() verwenden, da wir keine Verbindung herstellen müssen.

Nach dem Erstellen des Sockets können wir direkt mit der Kommunikation mit dem Server beginnen, indem wir die Methoden sendto() und recvfrom() verwenden. Vergessen Sie nach der Kommunikation mit dem Server nicht, den Socket mit der Methode close() zu schließen.

Mit dem folgenden Python-Programm können Sie einen Clientprozess implementieren, der mit dem UDP-Protokoll kommuniziert.

import socket

mySocket = socket.socket(
    family=socket.AF_INET, type=socket.SOCK_DGRAM, proto=0, fileno=None
)
print("Socket created.")
while True:
    msg = "Hi I am a UDP client created by Aditya."
    print("Sending msg to the server:", msg)
    mySocket.sendto(msg.encode(), ("localhost", 9999))
    msg_in = mySocket.recv(1024).decode()
    print("Acknowledgment received from the server:")
    print(msg_in)
    print("Terminating the Connection.")
    mySocket.close()
    break

Auch hier sollten Sie zum Beobachten der Ausgabe sowohl das Clientprogramm als auch das Serverprogramm gleichzeitig ausführen, damit beide Prozesse gleichzeitig aktiv sein und miteinander kommunizieren können.

Die Ausgabe im Terminal mit dem Serverprogramm sieht dann so aus:

Socket created.
Socket bound to address localhost and port number 9999
Message received from the client:
Hi I am a UDP client created by Aditya.
Sending acknowledgment to the client.

Die Ausgabe im Terminal mit dem Client-Programm sieht so aus:

Socket created.
Sending msg to the server: Hi I am a UDP client created by Aditya.
Acknowledgment received from the server:
Message received: b'Hi I am a UDP client created by Aditya.'. Thank you.
Terminating the Connection.

Fazit

In diesem Artikel haben wir die Socket-Programmierung in Python besprochen. Wir haben auch Client- und Serverprogramme separat implementiert, indem wir die TCP- und UDP-Protokolle verwendet haben, um die Grundlagen der Socket-Programmierung in Python zu erlernen.

TCP ist verbindungsorientiert und daher ein zuverlässiges Protokoll. Bei Verwendung des TCP-Protokolls ist gewährleistet, dass die Nachrichten vom Server zum Client und umgekehrt gelangen. Bei UDP ist nicht garantiert, dass die Nachricht an das gewünschte Ziel zugestellt wird.

Andererseits ist das UDP-Protokoll schneller und einfacher zu implementieren, während das TCP-Protokoll langsamer ist. Außerdem kann das TCP-Protokoll nicht zum Senden verwendet werden, während wir das UDP-Protokoll zum Senden verwenden können.

Abhängig von den verfügbaren Ressourcen und Ihrem Bedarf können Sie ein beliebiges Protokoll auswählen, um die Client-Server-Kommunikation über Sockets zu implementieren.

Autor: Aditya Raj
Aditya Raj avatar Aditya Raj avatar

Aditya Raj is a highly skilled technical professional with a background in IT and business, holding an Integrated B.Tech (IT) and MBA (IT) from the Indian Institute of Information Technology Allahabad. With a solid foundation in data analytics, programming languages (C, Java, Python), and software environments, Aditya has excelled in various roles. He has significant experience as a Technical Content Writer for Python on multiple platforms and has interned in data analytics at Apollo Clinics. His projects demonstrate a keen interest in cutting-edge technology and problem-solving, showcasing his proficiency in areas like data mining and software development. Aditya's achievements include securing a top position in a project demonstration competition and gaining certifications in Python, SQL, and digital marketing fundamentals.

GitHub

Verwandter Artikel - Python Socket

Verwandter Artikel - Python Module