Socket recv - abfragen wenn keine Daten mehr im Buffer

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Luiki
User
Beiträge: 6
Registriert: Sonntag 16. November 2014, 16:15

Hallo, ich hab in diversen Bsp-Codes Schleifen gefunden, die Daten mit recv auslesen bis keine mehr sind, aktuell hab ich:

Code: Alles auswählen

# Receive request
        while True:
            data = conn.recv(16)  
            if data:
                print data
            else:
                break
Wenn ich es debugge hängt das Programm bei den recv() -Aufruf nachdem alle Daten eigtl ausgelesen worden sind. Was ich erwarten würde is ein NULL-data und damit der else-Fall. Bei mir tritt der else-Fall, jedoch nie ein
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:


GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Luiki
User
Beiträge: 6
Registriert: Sonntag 16. November 2014, 16:15

hab ich schon gelesen aber
erstens wird hier eine angepasste recv-fkt geschrieben (dürfte ja für so ne std anwendung nicht notwendig sein
zweitens weiß ich ja nicht wieviele bytes angekommen sind es soll einfach der komplette buffer ausgelesen werden
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@Luiki: es kommt halt sehr darauf an, was Du machen willst. Normalerweise erwartet man ja eine bestimmte Anzahl an Bytes, wenn die gelesen sind, wird die Schleife beendet. Oder man merkt, dass keine Daten mehr kommen, weil der Socket geschlossen wird. Keine Daten im Puffer heißt halt nicht automatisch, alle Daten empfangen, sondern meistens, die Leitung ist zu langsam.
BlackJack

@Luiki: Diese Schleife liest alle Daten, also alle die da jemals kommen werden, also so lange bis die Gegenseite die Verbindung schliesst. Wenn Dein Programm also nicht endet, dann ist die Verbindung immer noch offen, da könnten also noch Daten kommen, `recv()` wartet also darauf. Irgendwelche Puffer kannst Du so nicht abfragen. Das ginge mit `select()` aus dem gleichnamigen Modul, aber bevor Du damit etwas machst, solltest Du vielleicht erst einmal verraten was Du da *eigentlich* machen willst, denn Deine Frage deutet auf Missverständnisse hin wie TCP funktioniert. Das ist ein Datenstrom von dem ein `recv()`-Aufruf einen Ausschnitt liefert der mindestens 1 Byte liefert (solange die Verbindung offen ist) bis maximal die angegebene Zahl von Bytes. Welcher Ausschnitt das ist muss *nichts* damit zu tun haben wie die Daten beim Sender auf die Reise geschickt wurden. `recv()` ist also in der tat alleine ziemlich doof und man wird sich so ziemlich *immer* eine Hilfsfunktion oder Klasse schreiben müssen!
Luiki
User
Beiträge: 6
Registriert: Sonntag 16. November 2014, 16:15

ich möchte die funktion eines http-servers nachahmen, d.h.

GET von client
antwort vom server
evtl weiteres GET von client etc

sollte ich also für jede anfrage/antwort einen neuen socket öffnen?
BlackJack

@Luiki: Grundsätzlich ja, HTTP kennt allerdings auch die Möglichkeit eine Verbindung für mehr als eine Anfrage/Antwort zu verwenden. Das steht in der HTTP-Spezifikation.

Edit: Die meisten Browser verwenden die Verbindung heutzutage anscheinend für mehr als eine Anfrage. Da musst Du also die Anfragen ordentlich auseinanderhalten beim empfangen.
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@Luiki: HTTP ist ein zeilenbasiertes Format, Du mußt also immer bis zum Ende einer Zeile lesen und diese verarbeiten. Damit ist das natürliche Ende der while-Schleife vorgegeben.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Luiki hat geschrieben:ich möchte die funktion eines http-servers nachahmen, d.h.
Warum gehst du dann so in die Tiefe und nutzt nicht https://docs.python.org/3/library/http.server.html ?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Luiki
User
Beiträge: 6
Registriert: Sonntag 16. November 2014, 16:15

@jens: ich möchte keinen echten http-server, ist nur zu übuzngszwecken für ein anderes projekt

@Sirius3: wie erkenne ich das Ende einer Zeile? "\n"?
BlackJack

@Luiki: Bei HTTP eigentlich '\r\n' aber man sollte mit beidem klarkommen. Nicht jeder Client hält sich 100%ig an HTTP. :-)

Wobei man nicht nur die erste Zeile lesen darf, sondern auch eventuell gesendete Header. Das Endkennzeichen davon ist eine Leerzeile. Je nach dem was Du von HTTP untserstützen möchtest, können danach dann noch Daten kommen. Wie viele Bytes das sind steht in dem Fall im Header 'Content-Length'.
Antworten