Netzwerk

Aus hyperdramatik
Zur Navigation springen Zur Suche springen


Was ist ein Netzwerk?

schema eines netzwerks
Wenn mehrere Geräte miteinander Daten austauschen, spricht man oft von Netzwerkkommunikation. Das wohl bekannteste Netzwerk ist das sogenannte Internet. :-)
Damit die Kommunikation zwischen unterschiedlichen Geräten gelingen kann, nutzt jedes Netzwerk eine Reihe von Netzwerkprotokollen und Standards, über die der Austausch von Daten geregelt ist, so dass alle an der Kommunikation beteiligten Geräte die verschickten und empfangenen Daten interpretieren können. In einem Netzwerk werden Daten über Protokolle Codiert und Decodiert und über Standards übertragen, beispielsweise über Twisted Pair Kabel (oft auch LAN Kabel genannt) oder über WiFi (mit unterschiedlichen Namen für die Übertragungsstandards, wie 802.11b, Bluetooth, etc.).
Netzwerke kann man selber machen, oder sich an bereits bestehende Netzwerke anschliessen.

Ein Netzwerkbeispiel

Netzwerkskizze.jpg
In diesem Netzwerk befinden sich drei Computer und ein Tablet. Die Computer und das Tablet sind über WiFi mit dem Access Point (oder auch Router) verbunden und beziehen darüber eine IP-Adresse, durch die Sie sich gegenseitig Nachrichten schicken können. Die Arduinos sind über Serial Communication mit den Computern verbunden.

Ist jede Kommunikation immer Netzwerkkommunikation?

Device connection example.jpg
Tatsächlich gab es Computerkommunikation bereits bevor der Netzwerkgedanke sich in jegliche Form der Kommunikation eingeschlichen hat. Eine Maus oder ein Keyboard ist ebenso ein Gerät, dass mit dem Computer kommuniziert. Ein Drucker beispielsweise auch. Der Unterschied besteht in diesem Fall darin, dass diese Geräte immer nur direkt mit dem Computer Daten austauschen, mit dem Sie auch verbunden sind. Es besteht also eine direkte Verbindung zwischen Gerät und Computer. An dieser Kommunikation nimmt niemand Drittes Teil. Deswegen spricht man in diesem Fall für gewöhnlich nicht von Netzwerkkommunikation.
Die Idee eines Netzwerks ist, dass eine unbestimmte Anzahl von Geräten miteinander in Kommunikation treten können. Auch wenn ein Netzwerk so aufgebaut sein kann, dass es über Regulierung bestimmte Teilnehmende ausschliesst.
Trotzdem benutzen auch diese Geräte, ebenso wie Geräte im Netzwerk, bestimmte Protokolle um Daten mit dem Computer auszutauschen. Im Bild oben sind einige der Protokolle und Standards etwas vereinfacht abgebildet.

Protokolle

Trying to communicate.jpg

Ein Protokoll ist die Vereinbarung, die sowohl Sender als auch Empfänger benutzen, um Daten in der gegenseitigen Kommunikation zu Codieren bzw. zu Decodieren. Oft bauen verschiedene Protokolle aufeinander auf, so das selten nur ein einziges Protokoll genutzt wird. Deswegen spricht man bei Protokollen oft von einem Schichtenmodell. Das bekannteste Schichtenmodell ist das OSI Schichtenmodell.

Vereinfachtes Schema

Für unseren Bereich müssen wir nicht alle Schichten des OSI Modells immer im Kopf haben. Deswegen können wir von ungefähr drei verschiedenen Schichten ausgehen, um die Dinge ein bisschen zu vereinfachen, und damit wir das hier ein bisschen besser erklären können. Im Kontext von Spiel und Objekt hilft es, sich drei verschiedene Schichten vorzustellen, über die wir uns unterhalten, die ich hier jetzt vereinfacht mal als:

  • Hardware (z.B.: Kabel mit 2 Drähten, Kabel mit 24 Drähten, Funk, Infrarot, Ultraschall, usw.)
  • Netzwerk (z.B.: IP, Serial, Mesh Network, usw.)
  • Daten (z.B.: OSC, MQTT, ASCII, Byte-Encoding, etc.)

aufgemalt habe:
Hardware network data.jpg
Wichtig ist in diesem Zusammenhang, dass die drei Schichten aufeinander aufbauen. Je nachdem, für welche Hardware-Schicht ich mich entscheide, stehen mir unterschiedliche Netzwerkprotokolle zur Verfügung. Je nach Netzwerkprotokoll stehen mir dann unterschiedliche Protokolle zur Datenübertragung zur Verfügung. Protokolle kann man selber machen, oder sich ein bereits vorgefertigtes aussuchen. In der Praxis stellen sich folgende Fragen an diese drei Ebenen:
Hnd explained.jpg

Protokolle die wir viel und gerne nutzen

Wenn man mit Computern kommuniziert sind Protokolle oft bereits auf der Hardware-Ebene und der des Betriebssystems vorhanden. So kann jeder PC und jedes Smartphone von Haus aus bereits das IP Protokoll, sowie das TCP und UDP Protokoll auswendig. Alle Programme, die miteinander sprechen wollen und die wir programmieren, können also auf diese Protokolle zugreifen.

Bei Microcontrollern wie dem Arduino sieht die Sache ein wenig anders aus. Dort ist als Hardware Ebene meist nur ein USB-Anschluss vorhanden - Arduino hat beispielsweise keinen WiFi Funkchip, und auch keinen Netzwerkkabelanschluss. Dementsprechend nutzen wir Hardwarebedingt bei Arduino meistens Serial Communication auf dem Netzwerk Layer. Es gibt durchaus Microcontroller mit solchen Anschlüssen, wie beispielsweise den ESP32, oder auch Zusatzplatinen, die mit mehr oder weniger Aufwand solche Funktionalität bereitstellen können. In diesen Fällen werden diese beiden Protokolle meist über Code und Libraries in eure Programme mit eingebunden.

Unser Hardware-Layer

Im Studium nutzen wir WiFi, das ihr auch aus eurem täglichen gebrauch kennt. Hiermit verbinden wir Tablets, Computer, Raspberry Pis und viele weitere Devices.
Hinzu kommt noch Ethernet oder auch gerne LAN -Kabel, was nichts anderes als eine kabelgebundene Version desselben Computernetzwerks ist. Die Kabel selbst werden oft auch als "Twisted Pair" Kabel bezeichnet (macht aber eigentlich kaum jemand. Für gewöhnlich sagen alle "Hast du noch ein LAN-Kabel für mich?"). Viele Laptops haben leider keinen eigenen LAN- oder Ethernet Anschluss mehr, damit sie dünner sein können.

  • Ethernet ist stabiler, weniger anfällig für Störungen und schneller
  • WiFi ist komfortabler und oft die einzige Möglichkeit der Anbindung (Tablets, Smartphones)

Wenn wir mit Mikrocontrollern wie Arduino arbeiten, nutzen wir für gewöhnlich USB Kabel.

Unser Netzwerk-Layer

IP, TCP, UDP und Serial Communication sind die Protokolle die wir in unserer Arbeit benutzen und sie bilden die Grundlage unseres Netzwerklayers.

Unser Daten-Layer

Darauf aufbauend gibt es dann im Kontext des Curriculums Spiel und Objekt noch zwei High-Level Protokolle, die das Codieren und Decodieren von Daten sehr viel einfacher machen. Für uns sind das OSC und MQTT, die als Library für die meisten Computer-Programmierumgebungen zur Verfügung stehen.

Wenn wir mit Serial Communication arbeiten, schreiben wir unsere Codierung und Decodierung, aufbauend auf die von Serial Communication zur verfügung gestellte codierung als Byte, für gewöhnlich selbst.

Serial, IP, UDP, TCP usw. erklärt

Serial Communication

Bei Serial Communication wird davon ausgegangen, dass beide Geräte einen Serial Port besitzen, mit einem Kabel miteinander verbunden sind, und dieser Serial Port so konfiguriert ist, dass Datenpakete als Bytes in einer gewissen Geschwindigkeit (Bytes Pro Sekunde, oder auch Baud) hintereinander gesendet werden.
Für gewöhnlich sind Serial Ports auf 9600 baud konfiguriert, weil nur kleine Datenmengen, etwa Sensordaten, ausgetauscht werden.
Mehr und vollständigeres Wissen zum Thema Serial Communication auf Hard- und Softwareebene gibt es bei Sparkfun.

Beispiel Arduino zu Processing

Um mit einem Arduino zu einem Processing Sketch zu kommunizieren, nutzen wir für gewöhnlich das USB Kabel des Arduino (Hardware Layer). Aufbauend auf diesem Kabel, haben Arduino und Processing bereits eine Vereinbarung getroffen, wie sie am Besten miteinander kommunizieren können: Serial Communication!
Arduino computer serial.jpg

Bei serieller Kommunikation werden die Datenpäckchen als Bytes nacheinander über das USB Kabel verschickt. Der Computer holt die Pakete nacheinander an einer Seriellen Schnittstelle ab. Diese Schnittstelle (oder Interface) wird in Windows auch als COM Port bezeichnet. Deswegen könnt ihr beim Arduino Programm auch den COM-Port einstellen.

ACHTUNG! ein Port kann immer nur von einem Programm gleichzeitig benutzt werden. Wenn ihr ein Programm laufen habt, dass den COM-Port belegt (zum Beispiel ein Processing Sketch), dann könnt ihr keinen neuen Code auf euren Arduino hochladen, solange dieses Programm noch läuft. Umgekehrt gilt das genauso: Wenn eure Arduino-Entwicklungsumgebung auf dem Computer läuft, kann ein Processing Sketch nicht auf den COM-Port zugreifen.

Jetzt kommen Daten an, aber was tun wir damit?

Das Arduino programm auf eurem Computer benutzt genau dieselbe Schnittstelle um für euch euren Arduino zu programmieren. Jedes Mal wenn ihr im Arduino programm auf Upload drückt, findet eine serielle Kommunikation mit dem Arduino statt. Diese Kommunikation ist so Codiert (im Data-Layer), dass das Arduino Gerät weiss, dass die nachfolgenden Daten dann Programmcode sind, die es demnächst dann ausführen soll.
Mit Hilfe der Serial Library könnt ihr diese Schnittstelle auch in eurem eigenen Code zum Datenaustausch zwischen dem Computer, auf dem bspw. Processing läuft, und eurem programmierten Arduino benutzen. Dazu müssen sowohl Arduino als auch Processing einige Verabredungen treffen:

  • beide müssen sich darauf einigen, in welcher Geschwindigkeit die Daten hintereinander geschickt und abgerufen werden (die sogenannte baud rate).
  • Processing muss zudem den Serial Port öffnen, damit der Computer weiss, dass die dort abgelegten Daten von Processing weiterverarbeitet werden.
  • schliesslich müsst ihr euch in eurem Code entscheiden, wie ein übertragenes Byte interpretiert werden soll. Ist es ein ASCII Zeichen? Ist es eine Zahl zwischen 0 und 255? Das müsst ihr in eurem Code in Arduino und Processing jeweils selbst festlegen, damit die beiden Programme jeweils verstehen, was sie mit den übertragenen Daten anfangen sollen.

Arduino sensor integer byte.jpg

Im Beispiel Arduino -> Processing würdet ihr als ein USB Kabel als Hardware Layer nutzen, als Netzwerk-Layer würdet ihr Serial Communication verwenden und dort die Baud-Rate einstellen, damit bei beiden die Geschwindigkeit der Datenübertragung klar ist, und auf der Datenebene würdet ihr euch ein eigenes Protokoll schreiben, dass die Interpretation der einzelnen kommunizierten Bytes zulässt.

Kommentierter Beispielcode

Hier dazu ein kommentiertes Beispiel: Arduino_Processing_Serial

IP und TCP, UDP

Wenn mehrere Computer, Smartphones oder Tablets miteinander Daten austauschen sollen, nutzen wir meistens Ethernet oder WiFi, und das darauf aufbauende IP Protokoll.
Ip packet.jpg

Das IP Protokoll ist auch die Basis der Netzwerkkommunikation mit dem Internet. Im Gegensatz zur Serial Communication werden die Datenpakete nicht einfach nur als Bytes, sondern mit einer ganzen Menge zusätzlicher Informationen auf die Reise durch den Hardware Layer geschickt. So beinhaltet ein IP-Packet unter anderem Informationen zum Absender, Empfänger, wieviele Daten es beinhaltet, und noch ein paar weiter mehr oder weniger spannendere Informationen.

IP Adressen

Absender und Empfänger haben in diesem Protokoll eine eindeutige Adresse zugewiesen, so dass das Paket weiss, von wem es kommt (damit man dorthin antworten kann) und wo es hin soll. Diese Adressen werden meistens über das Betriebssystem konfiguriert. Sie sind für die meisten unserer Anwendungen als vier aufeinanderfolgende Bytes codiert:

byte.byte.byte.byte

Die Einschränkung auf Bytes bedeutet nur, dass nur Zahlen zwischen 0 und 255 als Adresse vergeben werden können. Also eine Adresse ist dann:

x.x.x.x

wobei x jeweils eine Zahl von 0-255 ist.

Eine IP Adresse kann also so aussehen:

192.168.100.10

Oder so:

80.54.254.1

IP Adressen machen Sinn für Netzwerke, in denen die Kommunikation nicht mehr ausschliesslich zwischen zwei Geräten stattfindet. Wenn man also mehr als 2 geräte in einem Netzwerk hat, kann über die Adresse herausgefunden werden, an wen die Kommunikation gehen soll. Deswegen eignet sich das IP Protokoll für Netzwerke, in denen sehr viele Geräte miteinander kommunizieren.

Es gibt eine Vereinbarung, nach der die IP-Adresse 127.0.0.1 immer die IP-Adresse des eigenen Computers ist. Wenn ihr also IP-Päckchen an 127.0.0.1 schickt, kommen die bei euch selbst wieder an. So kann man z.B. Pakete von einem Processing Sketch zu einem anderen schicken, oder auf demselben Computer zwischen zwei Programmen (z.B. Processing und Unity) kommunizieren.

Eine weitere Vereinbarung ist, dass Adressen in lokalen Netzwerken für gewöhnlich immer mit 192.168. beginnen.

Router, Switches, Access Points

Ein Netzwerk kann mit, oder ohne Internet existieren. Wenn ein Netzwerk ohne Internet vorhanden ist, dann spricht man von einem Lokalen Netzwerk. Dieses lokale Netzwerk kommuniziert über einen Router, der sich im idealfall im Raum befindet. Dieser Router ist mit der Aufgabe betraut, Päckchen von Informationen hin und her zu schicken. Dazu verteilt der Router automatisch und in Eigenregie, an alle Devices die mit ihm Verbunden sind/eingeloggt sind, eine IP Adresse. Die Vergabe der IP Adresse kann aber auch manuell festgelegt werden, sodass ein Device immer dieselbe IP Adresse verwendet.
Wichtig: Manchmal muss die Firewall ausgeschalten sein um in einem Netzwerk kommunizieren zu können. Hier kann man die Handhabe der IP Adresse unter Windows festlegen: Windows IP Einstellungen

Wir verwenden die Begriffe Router, Switch und Access Point meistens Synonym. Sie bezeichnen die Schaltzentrale, über die IP-Adressen vergeben werden und sind meist eines oder mehrere Geräte, die dafür sorgen, dass alle Computer im Netzwerk eine IP-Adresse haben zu der man Daten schicken kann.
Switch-and-ap.jpg

Ports

Auf der Ebene des Betriebssystems (Windows, Linux, Mac OS, Android, etc...) werden die Pakete die über das IP-Protokoll ankommen bestimmten Ports zugewiesen. Ports sind vereinheitliche Adresszusätze, die es dem Betriebssystem ermöglichen, die angekommenen Pakete direkt an Programme weiterzuleiten, die zuvor beim Betriebssystem Zugriff auf einen Port beantragt haben. Dadurch wird unter anderem verhindert, dass alle Programme auf alle Netzwerkpakete zugreifen können. Wenn ihr Code schreibt, der Daten über das IP-Protokoll verschickt, werdet ihr euch beim Betriebssystem auch immer einen Port für die Übertragung reservieren wollen. Dieser wird vom Sender, ähnlich wie eure IP-Adresse, dann als Teil des Packets mitgeschickt, damit der Empfänger das Packet an das richtige Programm (das den Port beim Betriebssystem reserviert hat) weiterleiten kann. So können zwei Programme miteinander kommunizieren, ohne dass andere Programme in ihrer Kommunikation gestört werden. Hier gibt es mehr Infos zu Ports
Ports-and-os.jpg

Ports sind als eine ganze 16bit Zahl kodiert. Einem Computer stehen also 65536 Ports zur Verfügung. Als Faustregel gilt, niemals bei eigenen Projekten ports unter 1000 benutzen, weil viele dieser Ports von bestehenden Verabredungen (und Programmen) reserviert sind.

Das TCP-Protokoll

TCP baut auf das IP Protokoll auf und ist eine Vereinbarung, die getroffen wurde, um die Übertragung von Daten über grössere Distanzen und komplexere Netzwerke stabiler machen soll. Bei der Übertragung von Daten über TCP/IP wird für jedes IP-Packet abgefragt, ob die Daten denn auch wirklich angekommen sind. Im Zweifel wird dasselbe Packet nochmal verschickt. TCP sorgt auch dafür, dass die Packets in der richtigen Reihenfolge ankommen. Das macht TCP ein wenig langsam, aber dafür sehr viel stabiler in der Kommunikation als beispielsweise UDP. Mehr Infromationen zu TCP gibt es hier.
Tcp-joke.jpg

Das UDP-Protokoll

Aufbauend auf das IP-Protokoll, das dafür sorgt, dass die Pakete an der richtigen IP-Adresse ankommen, und das der Absender bekannt ist, wird für die Datenübertragung in lokalen Netzwerken oft das UDP Protokoll genutzt.
Udp-joke.jpg

Das UDP-Protokoll ist ein sehr einfaches Protokoll, bei dem Daten (ähnlich wie bei Serial Communication) als Bytes übetragen werden. Der Empfänger muss dann eigenständig schauen, wie diese Daten interpretiert werden. Alles was UDP bereitstellt ist, wieviele Bytes übermittelt werden sollten sowie die Bytes selbst. Sollte bei der Netzwerkübertragung Fehler auftreten - z.B. ein Päckchen verloren gehen, oder ein Päckchen zu spät ankommen - hat der Empfänger keine Möglichkeit das nachzuverfolgen. Mehr Informationen zum UDP Protokoll

OSC als Ordnungsmethode im Daten-Layer

Das OSC Protokoll baut auf das IP-Protokoll sowie das UDP Protokoll auf. Es funktioniert also am Besten in lokalen Netzwerken. Wir verwenden es für gewöhnlich als library in unseren jeweiligen Entwicklungsumgebungen (Processing und Unity).
Der Grund wieso wir das OSC-Protokoll mögen ist, dass es uns erlaubt, die Daten die wir zwischen Programmen hin- und herschicken bereits mit Variablentypen zu verbinden. So können wir über OSC zum Beispiel einen String, eine Float oder eine Int Variable schicken, ohne das wir uns selbst über deren Codierung und decodierung aus Bytes kümmern müssen.
Das OSC-Protokoll verwendet einige Begriffe innerhalb des Codes:

  • eine OSC-Message ist ein Bündel von Daten, in denen eine OSC-Adresse und mehrere Datenwerte unterschiedlichen Typs zusammengefasst sind. Sie bezeichnet eine einzelne Übetragungseinheit, das heisst, alles in einer OSC-Message wird auf einen Rutsch übertragen.
  • Eine OSC-Adresse ist ein String der uns zur Verfügung gestellt wird, um die angekommenen Datenwerte zu sortieren. Meistens können wir uns die Adresse aussuchen und sie ist nur in komplexeren Projekten relevant. Die Adresse besteht zusätzlich zur IP-Adresse und zum Port.
  • Die Werte des OSC-Bündels die einen bestimmten Typ haben, den wir beim Empfang abfragen können.

OSC ist sehr hilfreich bei der Datenübertragung, verhindert aber nicht, dass wir trotzdem eine Reihenfolge bei der Übertragung von Daten festlegen sollten. Obwohl OSC die codierung und decodierung für uns vornimmt, ist es wichtig, dass in OSC in unserem Empfangscode die richtige decodierung für jeden Wert anwenden.

In Processing benutzen wir die oscP5 Library von Andreas Schlegel, die anhand der damit installierten Beispiele gut nachzuvollziehen ist. Sie ist hier auch nochmal online dokumentiert.
Die Library kann über den Processing Library Manager installiert werden, wenn man dort nach oscP5 sucht.

 Select "Add Library..." from the "Import Library..." submenu within the Sketch menu. 

Ein Beispiel für die Implementierung von OSC in Unity ist hier zu finden: OSC in Unity

Verbindungsbeispiele

  • Um von Arduino Daten (z.B. Sensorwerte) and ein Computerprogramm (z.B. Processing oder Unity) zu senden, benutzen wir für gewöhnlich ein USB-Kabel und Serial Communication, und schreiben unsere Dateninterpretation dann meistens selber. Siehe auch das Beispiel unten.
  • Um von einem Programm (z.B. Processing oder Unity) an ein anderes Programm (z.B. Unity oder Processing) innerhalb eines Raumes Daten zu schicken (z.B. Antworten auf eine Frage, die dann auf einem anderen Computer visualisiert werden), benutzen wir meist WiFi, das IP Protokoll (genauer IPv4) und dann die OSC library, um die Daten zu interpretieren. Siehe auch das Beispiel weiter unten.
  • Um von einem Processing Sketch Daten an einen anderen Processing Sketch irgendwo anders auf der Welt zu senden, benutzen wir meist WiFi, das IP Protokoll und die MQTT library. Siehe auch das Beispiel weiter unten.

Sticklebrick Communication

A failed attempt at explaining communication using bricks as bits.