187 lines
5.8 KiB
Plaintext
187 lines
5.8 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"pycharm": {
|
|
"name": "#%% md\n"
|
|
},
|
|
"slideshow": {
|
|
"slide_type": "slide"
|
|
}
|
|
},
|
|
"source": [
|
|
"# Software Entwicklung \n",
|
|
"\n",
|
|
"## Kapitel 9: IO\n",
|
|
"\n",
|
|
"### 9.5 Sockets\n",
|
|
"\n",
|
|
"So wie der Begriff *Datei* eine griffige Bezeichnung für eine Ansammlung dauerhaft gespeicherter Bytes ist, wird\n",
|
|
"mit *Socket* ein Endpunkt für Netzwerkverbindungen bezeichnet.\n",
|
|
"Die Kommunikation findet zwischen zwei Sockets *bidirektional* statt, d.h. über jedes Socket können Bytes versendet\n",
|
|
"und empfangen werden."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"pycharm": {
|
|
"name": "#%% md\n"
|
|
},
|
|
"slideshow": {
|
|
"slide_type": "slide"
|
|
}
|
|
},
|
|
"source": [
|
|
"Sockets stehen in Python durch das Standard-Modul <code>sockets</code> zur Verfügung. Wie schon Dateien belegen auch\n",
|
|
"Sockets Betriebssystem-Ressourcen, so dass die Verwendung eines Kontextmanagers ratsam ist."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"pycharm": {
|
|
"name": "#%%\n"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import socket\n",
|
|
"\n",
|
|
"with socket.socket() as s:\n",
|
|
" pass"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"slideshow": {
|
|
"slide_type": "slide"
|
|
}
|
|
},
|
|
"source": [
|
|
"#### 9.5.1 Client-Server-Modell\n",
|
|
"\n",
|
|
"Zwar sind bei einer bestehenden Kommunikationsverbindung zwischen zwei Sockets die beiden Sockets prinzipiell\n",
|
|
"gleichberechtigt, jedoch gibt es Unterschiede beim Kommunikationsaufbau.\n",
|
|
"\n",
|
|
"* Ein *Server-Socket* verhält sich passiv, d.h. es wartet auf eingehende Verbindungsanfragen. Trifft eine solche\n",
|
|
" ein, generiert es ein weiteres Socket, das fest dieser Verbindung zugeordnet wird und über das die\n",
|
|
" anschließende Kommunikation abgewickelt wird. Das *Server-Socket* selbst verbleibt im Wartezustand.\n",
|
|
"\n",
|
|
"* Ein *Client-Socket* übernimmt den aktiven Part. Es kontaktiert das *Server-Socket* und geht selbst die\n",
|
|
" Verbindung mit dem daraufhin bereitgestellten Socket ein."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"slideshow": {
|
|
"slide_type": "slide"
|
|
}
|
|
},
|
|
"source": [
|
|
"Die Verbindungsaufnahme folgt einem vorgegebenen Ablauf aus definierten Schritten (auch: *Kommunikationsprimitive*).\n",
|
|
"\n",
|
|
""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"pycharm": {
|
|
"name": "#%% md\n"
|
|
},
|
|
"slideshow": {
|
|
"slide_type": "slide"
|
|
}
|
|
},
|
|
"source": [
|
|
"#### 9.5.2 Server-Socket\n",
|
|
"\n",
|
|
"Ein *Server-Socket* ist eindeutig festgelegt durch das Protokoll (z.B. TCP oder UDP), den Rechner\n",
|
|
"(z.B. durch dessen IP-Adresse) und eine Portnummer. Letztere dient dazu, dass mehrere Server-Sockets gleichzeitig\n",
|
|
"auf einem Rechner existieren können, ohne sich gegenseitig zu beeinflussen.\n",
|
|
"\n",
|
|
"So gibt es z.B. auf dem Server <code>medinf.efi.th-nuernberg.de</code> mehrere Server-Sockets,\n",
|
|
"die permanent angesprochen werden können:\n",
|
|
"\n",
|
|
"* Port 22: Nimmt Secure-Shell-Anfragen entgegen\n",
|
|
"* Port 80: Nimmt HTTP-Anfragen entgegen\n",
|
|
"* Port 443: Nimmt HTTPS-Anfragen entgegen"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"pycharm": {
|
|
"name": "#%% md\n"
|
|
},
|
|
"slideshow": {
|
|
"slide_type": "slide"
|
|
}
|
|
},
|
|
"source": [
|
|
"Das *Server-Socket* wird mit <code>bind</code> an einen bestimmten Port und eine\n",
|
|
"IP-Adresse (ggf. hat ein Rechner mehrere IP-Adressen) gebunden. Das Binden schlägt fehl, wenn die\n",
|
|
"Kombination bereits von einem anderen Socket belegt ist.\n",
|
|
"\n",
|
|
"Anschließend beginnt das *Server-Socket* mit <code>listen</code> zu lauschen. Das Primitiv <code>accept</code>\n",
|
|
"blockiert den Server, bis ein *Client-Socket* Verbindung aufnimmt. Damit entsteht ein weiteres Socket mit\n",
|
|
"einer vom System vergebenen Portnummer, das dediziert nur für die Verbindung mit diesem Client verwendet wird.\n",
|
|
"\n",
|
|
"Über dieses neue Socket folgen danach Primitive zum Senden\n",
|
|
"<code>send</code> und Empfangen <code>receive</code> von Nachrichten. Anzahl und Abfolge sind\n",
|
|
"für Sockets nicht festgelegt, müssen aber zwischen Client und Server abgestimmt sein. So legt z.B.\n",
|
|
"das auf Sockets aufsetzende Protokoll HTTP fest, dass zunächst eine Nachricht vom Client\n",
|
|
"an den Server (*HTTP-Request*) und anschließend eine Nachricht vom Server an den Client\n",
|
|
"(*HTTP-Response*) gesendet wird. Während in der ersten Version von HTTP danach die\n",
|
|
"Verbindung wieder abgebaut wurde, ist es aktuellen Versionen möglich, dieses Abfolge\n",
|
|
"wiederholt über eine bestehende Verbindung abzuwickeln."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"pycharm": {
|
|
"name": "#%% md\n"
|
|
},
|
|
"slideshow": {
|
|
"slide_type": "slide"
|
|
}
|
|
},
|
|
"source": [
|
|
"Eine etablierte Verbindung ist mit <code>close</code> zu schließen. Bei Verwendung eines\n",
|
|
"Kontextmanagers erfolgt dies automatisch.\n",
|
|
"\n",
|
|
"Auch das *Server-Socket* muss geschlossen werden, um das Binden an einen Port zu beenden\n",
|
|
"und den Port freizugeben."
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"celltoolbar": "Slideshow",
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.9.9"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 1
|
|
}
|