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:41] 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 20: Zeile 16:
  
 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 =====
 +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.
 +Zur Kontrolle gibt er per ''print'' die empfangenen Daten in der Shell aus.
  
 <file python echo_server.py> <file python echo_server.py>
Zeile 40: Zeile 41:
                 break                 break
             conn.sendall(data)             conn.sendall(data)
 +            print('Client says:', repr(data))
 </file> </file>
 +
 +===== ECHO-Client =====
 +
 +Der Client schickt genau eine Nachricht an den Server und gibt per ''print'' das Echo (Antwort des Servers) in der Shell aus.
  
 <file python echo_client.py> <file python echo_client.py>
Zeile 57: 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.1568709660.txt.gz · Zuletzt geändert: 17.09.2019 10:41 von richard

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki