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
Letzte ÜberarbeitungBeide Seiten der Revision
lager:lok_netze:tcp_python [17.09.2019 10:35] richardlager:lok_netze:tcp_python [01.11.2019 09:29] richard
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ünblau), 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. 
 + 
 + 
 +===== Hinweise / Tipps ===== 
 + 
 +Folgender Code kann als Grundlage für einen sogenannten ECHO-Server dienen, der alle Daten an den Sender zurück schickt, die er empfangen hat. 
 + 
 +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 ''(HOSTPORT)'' 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> 
 +#!/usr/bin/env python3 
 + 
 +import socket 
 + 
 +HOST = '127.0.0.1'  # Hier sollte eine "echte" IP eingetragen werdenansonsten kann der Server nur von dem PC selbst erreicht werden 
 +PORT = 65432        # Port auf dem gelauscht (listenwird (nicht previligierte Ports > 1023) 
 + 
 +with socket.socket(socket.AF_INETsocket.SOCK_STREAM) as s: 
 +    s.bind((HOST, PORT)) 
 +    s.listen(0)            # Auf der Real Python-Seite fehlt der Parameter 0, so dass es zu Fehlermeldungen kommt 
 +    conn, addr = s.accept() 
 +    with conn: 
 +        print('Connected by', addr) 
 +        while True: 
 +            data = conn.recv(1024) 
 +            if not data: 
 +                break 
 +            conn.sendall(data) 
 +            print('Client says:', repr(data)) 
 +</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> 
 +#!/usr/bin/env python3 
 + 
 +import socket 
 + 
 +HOST = '127.0.0.1'  # Hostname oder IP des Echo-Servers eintragen 
 +PORT = 65432        # Port des Servers eintragen 
 + 
 +with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 
 +    s.connect((HOST, PORT)) 
 +    s.sendall(b'Hello, world'
 +    data = s.recv(1024) 
 + 
 +print('Received', repr(data)) 
 +</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> 
 + 
  
-<code> 
-* für blau 
-- für rot 
-+ für grün 
-</code> 
  
  
  
lager/lok_netze/tcp_python.txt · Zuletzt geändert: 30.04.2023 15:46 von richard

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki