Fehlgeschlagene If-Abfrage

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
BlackJack

@kbr: Die ”magischen” Methoden sind in der Regel nicht zum direkten Aufrufen gedacht. Dafür ist die `repr()`-Funktion da.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

BlackJack hat geschrieben:@kbr: Die ”magischen” Methoden sind in der Regel nicht zum direkten Aufrufen gedacht. Dafür ist die `repr()`-Funktion da.
Ja, das stimmt natürlich. Danke, ändere ich mal, damit es nicht so als Beispiel stehen bleibt.
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@kbr: die receive_data-Funktion wird erst verlassen, wenn das schreibende Ende der Gegenseite geschlossen wird. Das dürfte viele Anfänger wundern, dass ihr Server scheinbar hängt, obwohl er noch auf Daten wartet, die nie kommen werden. Und dass eine Funktion, die send_data heißt, die Verbindung schließt, ist auch eher überraschend.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Sirius3: Das ist wohl richtig, aber das Beispiel orientiert sich auch an dem bisherigen Code von montus_pythonia ohne Neues einzuführen, mit Ausnahme des BytesIO-Buffers. Implizit bin ich davon ausgegangen, dass die Gegenseite tatsächlich den schreibenden Socket schließt. Ob das tatsächlich der Fall ist, müsste montus_pythonia mitteilen.
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@kbr: montus_pythonia liest nur 2mal 1-16 Bytes, was mit dem senden von z.B. 20 Bytes "testtesttesttesttest" erledigt wäre.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Sirius3 hat geschrieben:montus_pythonia liest nur 2mal 1-16 Bytes.
Was fragil ist; und vermutlich wird er die Frage, was der Server macht, d.h. ob der Server schließt oder wie das Protokoll lautet, auch nicht so einfach beantworten können. Womit wir wieder bei dem Punkt wären, dass Socket-Programmierung nicht trivial ist.
montus_pythonia
User
Beiträge: 10
Registriert: Donnerstag 27. August 2015, 18:51

So, "repr()" hat mir tatsächlich weitergeholfen, das Ergebnis wird immer in " ' " dargestellt, und es wird ein /r/n angehangen. Muss man halt wissen, wäre auch cool wenn jemand mir erklären könnte warum dass der Fall ist! Ich habe das jetzt so gemacht indem ich einen Teilstring aus data gebildet habe. Dieser kann jetzt mithilfe der If Abfrage erkannt werden. D.h. Problem gelöst! Vielen Dank nochmal dafür!
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@montus_pythonia: Da wird empfangsseitig kein /r/n angehangen (falls Du dies vermuten solltest), sondern dieses wird von Sendeseite mitgeliefert.
BlackJack

@montus_pythonia: Da ist nicht '/r/n' sondern '\r\n' an den Daten. Also ein Byte/Zeichen für Wagenrücklauf („carriage return“, CR) und ein Newline (NL) um die Zeile abzuschliessen. Und das kommt wie kbr schon sagte vom Sender. Und wenn Du weiterhin einfach ein `recv()` verwendest und die Daten aus diesem einen Aufruf sofort weiterverarbeitest dann ist Dein Programm immer noch fehlehaft. Das tut bei denen Tests vielleicht, aber das ist halt nicht garantiert.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Möglicherweise dient das sendeseitig angehangene '\r\n' als Terminator. Falls das richtig ist, ließe sich die Empfangsfunktion dann auch stabil implementieren.
montus_pythonia
User
Beiträge: 10
Registriert: Donnerstag 27. August 2015, 18:51

Ah Ok, wieder was gelernt ;)
Für meine Basteileien muss das überrings nicht super professionell umgesetzt sein, mit dem Ergebnis bin ich so zufrieden, auch wenn ich weiß das es sicher besser ginge :D
Dennoch natülich besten Dank an alle die sich mit mir rumschlagen hier ;)

Edit @BlackJack:
Ich verwende überrings nichtmehr recv() um die Daten zu verarbeiten sondern die Variable data, auch wenn es zwischendurch in einem meiner geposteten Codes hier stand, oder ist es nicht das was du meintest?
BlackJack

@montus_pythonia: Äh, und wo kommt der Inhalt von `data` her? Du verwendest `recv()` zumindest in den gezeigten Quelltexten falsch.
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Da es sich ja offensichtlich um ein zeilenbasiertes Protokoll handelt, läßt sich das Problem einfach lösen:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
import socket
import sys

def process(connection, client_address):
    print >>sys.stderr, 'Neue Verbindung mit:', client_address

    # Daten empfangen und zurückschicken
    for line in connection.makefile('r'):
        print >>sys.stderr, 'Daten empfangen:', repr(line)
        print >>sys.stderr, 'Daten werden zurückgeschickt'
        connection.sendall(line)
        if line.strip() == "test":
            print >>sys.stderr, "Data ist test!"
        else:
            print >>sys.stderr, "Data ist nicht test!"
    print >>sys.stderr,'Verbindung mit', client_address, 'beendet'


def mainloop():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    server_address = ('192.168.178.41', 21345)
    print >>sys.stderr, 'Server startet auf %s port %s' % server_address
    sock.bind(server_address)
    sock.listen(1)

    while True:
        print >>sys.stderr, 'Auf Verbindung warten'
        process(*sock.accept())

if __name__ == '__main__':
    mainloop()
Antworten