Benutzer-Werkzeuge

Webseiten-Werkzeuge


lager:lok_netze:tcp_python

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
lager:lok_netze:tcp_python [17.09.2019 10:45] richardlager:lok_netze:tcp_python [30.04.2023 15:46] (aktuell) – Status der Diskussion geändert richard
Zeile 1: Zeile 1:
-~~DISCUSSION|Ergänzungen~~+~~DISCUSSION:closed|Ergänzungen~~
 ====== Programmierung Übung zu TCP mit python ====== ====== Programmierung Übung zu TCP mit python ======
  
Zeile 7: Zeile 7:
  
   - Programmieren Sie eine einfache Client-Client-Anwendung bei der sich die jeweiligen Clients Nachricht per TCP zusenden.   - Programmieren Sie eine einfache Client-Client-Anwendung bei der sich die jeweiligen Clients Nachricht per TCP zusenden.
-  - Erweitern Sie die Nachrichten um Farben (rotgrün, blau), die zu Beginn des Textes mit einfachen Zeichen vom User ausgewählt werden sollen und auf der Empfangsseite farbig ausgegeben werden.+  - Erweitern Sie den Server zu einem Multi-Connection-Server, der mehr als eine Verbindung bedienen kann.  
 +  - Geben Sie eingehende Nachrichten an alle anderen Verbindungen aus.
  
-<code> 
-* für blau 
-- für rot 
-+ für grün 
-</code> 
  
 ===== Hinweise / Tipps ===== ===== Hinweise / Tipps =====
Zeile 21: Zeile 17:
 Der Code wird [[https://realpython.com/python-sockets/#echo-client-and-server|hier]] ausführlich erklärt. Der Code wird [[https://realpython.com/python-sockets/#echo-client-and-server|hier]] ausführlich erklärt.
  
-==== ECHO-Server ====+===== ECHO-Server =====
 Der Server binden sich auf den Socket ''(HOST, PORT)'' und lauscht (''conn.recv'') dort auf einkommende Daten. Der Server binden sich auf den Socket ''(HOST, PORT)'' und lauscht (''conn.recv'') dort auf einkommende Daten.
 Die empfanenen Daten sendet er an den Client per ''conn.sendall'' direkt zurück. Die empfanenen Daten sendet er an den Client per ''conn.sendall'' direkt zurück.
Zeile 48: Zeile 44:
 </file> </file>
  
-==== ECHO-Client ====+===== ECHO-Client =====
  
 Der Client schickt genau eine Nachricht an den Server und gibt per ''print'' das Echo (Antwort des Servers) in der Shell aus. Der Client schickt genau eine Nachricht an den Server und gibt per ''print'' das Echo (Antwort des Servers) in der Shell aus.
Zeile 67: Zeile 63:
 print('Received', repr(data)) print('Received', repr(data))
 </file> </file>
 +
 +==== Interaktiver Echo-Client ====
 +
 +<file python echo_client_interactive.py>
 +#!/usr/bin/env python3
 +
 +import socket
 +
 +HOST = '127.0.0.1'  # Hostname oder IP des Echo-Servers eintragen
 +# PORT = 65432        # Port des Servers eintragen
 +PORT = 50000
 +
 +host = input('Server-IP [' + HOST + ']: ')
 +port = input('Server-Port [' + str(PORT) + ']: ')
 +
 +if host != '':
 +    HOST = host
 +if port != '':
 +    PORT = int(port, 10)
 +
 +with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
 +    s.connect((HOST, PORT))
 +    written = ''
 +    while True:
 +        written = input('Your message (type "exit" to exit): ')
 +        if written == 'exit':
 +            break;
 +        s.sendall(bytearray(written, 'UTF-8'))
 +        data = s.recv(1024)
 +        print('Received ', repr(data))
 + 
 +print('Client closed')
 +</file>
 +
 +
 +
 +===== Multi-Connection-Server =====
 +
 +Quelle: Das Beispiel stammt ursprünglich von dieser [[https://steelkiwi.com/blog/working-tcp-sockets/ Seite]] und wurde leicht angepasst bzw. für ''python3'' lauffähig gemacht.
 +Als Client kann der ''ECHO''-Client von oben verwendet werden. Jede Anfrage führt zu einer neuen Verbindung.
 +
 +Diese Verbindungen können mittels:
 +<code>netstat -an | grep 50000</code>
 +angezeigt werden. Hier ist ''50000'' der LISTEN-Port des Servers. Ggf. muss ''localhost'' durch eine erreichbare IP-Adresse des betreffenden Server-PCs ausgetauscht werden.
 +
 +
 +<file python tcp_multi_server.py>
 +#!/usr/bin/env python3
 +
 +import select, socket, sys, queue
 +server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 +server.setblocking(0)
 +server.bind(('localhost', 50000))
 +server.listen(5)
 +inputs = [server]
 +outputs = []
 +message_queues = {}
 +
 +while inputs:
 +    readable, writable, exceptional = select.select(
 +        inputs, outputs, inputs)
 +    for s in readable:
 +        if s is server:
 +            connection, client_address = s.accept()
 +            connection.setblocking(0)
 +            inputs.append(connection)
 +            message_queues[connection] = queue.Queue()
 +        else:
 +            data = s.recv(1024)
 +            if data:
 +                message_queues[s].put(data)
 +                if s not in outputs:
 +                    outputs.append(s)
 +            else:
 +                if s in outputs:
 +                    outputs.remove(s)
 +                inputs.remove(s)
 +                s.close()
 +                del message_queues[s]
 +
 +    for s in writable:
 +        try:
 +            next_msg = message_queues[s].get_nowait()
 +        except queue.Empty:
 +            outputs.remove(s)
 +        else:
 +            s.send(next_msg)
 +
 +    for s in exceptional:
 +        inputs.remove(s)
 +        if s in outputs:
 +            outputs.remove(s)
 +        s.close()
 +        del message_queues[s]
 +</file>
 +
 +===== Keystroke als Command Line Handler =====
 +
 +ACHTUNG: Das folgende Beispiel funktioniert nur, wenn das Script direkt in der Shell ausgeführt wird. Hierzu muss zunächst die Datei ausführbar gemacht werden. Mit folgendem Befehl kann dies getan werden:
 +
 +<code>chmod +x keystroke_sample.py</code>
 +
 +Das folgende Bespiel wartet dauerhaft auf eine Eingabe und führt je nach Tastedruck Programmcode aus.
 +<file python keystroke_sample.py>
 +#!/usr/bin/env python3
 +
 +import sys, termios, tty, os, time
 + 
 +def getch():
 +    fd = sys.stdin.fileno()
 +    old_settings = termios.tcgetattr(fd)
 +    try:
 +        tty.setraw(sys.stdin.fileno())
 +        ch = sys.stdin.read(1)
 + 
 +    finally:
 +        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
 +    return ch
 +
 +while True:
 +    char = getch()
 + 
 +    if (char == "p"):
 +        print("Stop!")
 +        exit(0)
 + 
 +    if (char == "a"):
 +        print("Left pressed")
 +        time.sleep(1)
 +</file>
 +
 +
 +
 +
 +
  
lager/lok_netze/tcp_python.1568709900.txt.gz · Zuletzt geändert: 17.09.2019 10:45 von richard

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki