Moin,
bisher habe ich über eine Socketverbindung Daten von einem Server heruntergeladen. Die Datenmengen waren im 10kByte-Bereich und es hat problemlos funktioniert. Jetzt habe ich die Datenmenge verändert und es müssen bis ca. 1MByte Daten zurück geliefert werden und dann tritt ein Fehler auf.
An welchen Einstellungen sollte man drehen, damit auch größere Datenmengen übertragen werden?
Gruß Jan
große Datenmengen über eine Socketverbindung abrufen
Hallo und willkommen im Forum!
"Ein Fehler" ist eine recht unzureichende Fehlerbeschreibung und bei den meisten Forumsmitgliedern ist die Glaskugel leider ständig kaputt Es braucht also etwas mehr Information um dir helfen zu können. Wie sieht der Fehler aus? Bekommst du eine Exception und wie lautet diese und wie sieht der Traceback dazu aus? Wenn keine Exception geworfen wird: woran merkst du, dass es einen Fehler gibt? Was soll dein Programm machen und was passiert tatsächlich?
Hilfreich ist natürlich immer der betreffende Code. Am besten ist ein minimales LAUFFÄHIGES Beispiel, an dem man deinen Fehler nachvollziehen kann. Beim erstellen eines solchen Beispiels erledigen sich die Fehler häufg schon von alleine, da man selber drüber stolpert.
"Ein Fehler" ist eine recht unzureichende Fehlerbeschreibung und bei den meisten Forumsmitgliedern ist die Glaskugel leider ständig kaputt Es braucht also etwas mehr Information um dir helfen zu können. Wie sieht der Fehler aus? Bekommst du eine Exception und wie lautet diese und wie sieht der Traceback dazu aus? Wenn keine Exception geworfen wird: woran merkst du, dass es einen Fehler gibt? Was soll dein Programm machen und was passiert tatsächlich?
Hilfreich ist natürlich immer der betreffende Code. Am besten ist ein minimales LAUFFÄHIGES Beispiel, an dem man deinen Fehler nachvollziehen kann. Beim erstellen eines solchen Beispiels erledigen sich die Fehler häufg schon von alleine, da man selber drüber stolpert.
Das Leben ist wie ein Tennisball.
Moin,
es gibt keine Fehlermeldung. Da es sich um Testdaten handelt, weiß ich natürlich was hinten raus kommt.
Die letzen Daten werden nicht geliefert. Es ist eine Anfrage an eine Datenbank und es sollen gewünsche Feldinformationen von entsprechenden Datensätzen zurückgeliefert werden. Ich habe mir schon überlegt, ob ich nur die eindeutige Nummer der Datensätze hole und dann nach und nach die zusätzlichen Informationen einsammeln sollte. Aber vielleicht gibt es auch eine begrenzende Einstellung an der man noch was machen kann. Empfangsspeicher habe ich auf 8192 gestellt. Kann man den Eingangsspeicher beliebig vergrößern?
Ich werde mal versuchen die entscheiden Zeilen Code zusammenzufassen, da der Code nicht nur an einer Stelle des Programms steht.
Schöne Abend noch.
Gruß Jan
es gibt keine Fehlermeldung. Da es sich um Testdaten handelt, weiß ich natürlich was hinten raus kommt.
Die letzen Daten werden nicht geliefert. Es ist eine Anfrage an eine Datenbank und es sollen gewünsche Feldinformationen von entsprechenden Datensätzen zurückgeliefert werden. Ich habe mir schon überlegt, ob ich nur die eindeutige Nummer der Datensätze hole und dann nach und nach die zusätzlichen Informationen einsammeln sollte. Aber vielleicht gibt es auch eine begrenzende Einstellung an der man noch was machen kann. Empfangsspeicher habe ich auf 8192 gestellt. Kann man den Eingangsspeicher beliebig vergrößern?
Ich werde mal versuchen die entscheiden Zeilen Code zusammenzufassen, da der Code nicht nur an einer Stelle des Programms steht.
Schöne Abend noch.
Gruß Jan
@Stollberg: Wie gesagt macht das ohne Quelltext und genaue Fehlerbeschreibung nicht viel Sinn. Was ist für Dich zum Beispiel der `Empfangsspeicher`? Etwa das Argument von `recv()`? Wie gross das ist wäre zum Beispiel egal, denn man liesst ja sowieso *immer* in einer Schleife bis man sicher alle Daten zusammen hat.
Hier der Quellcode in Auszügen:
Es kommt keine Fehlermeldung, aber es sind noch nicht alle Daten da.
Code: Alles auswählen
import socket
self.cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.cs.connect((PrimaryServer,PrimaryPort))
self.Servermeldung = self.cs.recv(8192)
.......
# Es werden teilweise auch Daten verschickt und dan kommt nur eine kurze Antwort
self.cs.send(self.Command)#Daten schicken
neueMeldung = self.cs.recv(8192)
.....
while neueMeldung.startswith("%"): #wenn das erste Zeichen kein % ist,dann ist es die letzte Meldung
neueMeldung = self.cs.recv(8192)
.....
Sind es diese "%"-Meldungen, die auch mal größer als 8KB werden können, oder wie? Dein jetziger Code geht jedenfalls davon aus, dass immer maximal 8192 Bytes pro Meldung gesendet werden. Alles was größer ist, geht unter, da der Test für eine erneute Iteration der `while`-Schleife fehlschlägt. Denn eine abgeschnittene Meldung wird ja wahrscheinlich nicht mehr mit "%" beginnen.
Außerdem ist mir nicht so ganz klar, wieso der Name "neueMeldung" immer überschrieben wird. Soll das wirklich so sein? Entspricht dein tatsächlicher Code vielleicht doch nicht dem, was du hier zeigst? Ich kann mich hier nur anschließen, dass es wesentlich mehr bringen würde, wenn du ein lauffähiges Snippet zeigen würdest, welches den Fehler auch *tatsächlich* bei dir erzeugt.
Außerdem ist mir nicht so ganz klar, wieso der Name "neueMeldung" immer überschrieben wird. Soll das wirklich so sein? Entspricht dein tatsächlicher Code vielleicht doch nicht dem, was du hier zeigst? Ich kann mich hier nur anschließen, dass es wesentlich mehr bringen würde, wenn du ein lauffähiges Snippet zeigen würdest, welches den Fehler auch *tatsächlich* bei dir erzeugt.
@Stollberg: tcp ist ein stream-Protokoll, es gibt also soetwas wie Meldungen nicht!
Du mußt also immer solange Daten vom Server lesen, bis eine Meldung komplett ist. Viele Protokolle (HTTP, FTP, SMTP, usw.) sind zeilenbasiert.
Eine Zeile ist also eine »Meldung«. Z.B:
um den GET-Befehl abzusetzen.
Programmiere also Deine gesamte Leseroutinen so, dass sie auch mit socket.recv(1) zurechtkommen, denn das ist die garantierte Nachrichtenlänge .
Du mußt also immer solange Daten vom Server lesen, bis eine Meldung komplett ist. Viele Protokolle (HTTP, FTP, SMTP, usw.) sind zeilenbasiert.
Eine Zeile ist also eine »Meldung«. Z.B:
Code: Alles auswählen
GET /index.html
usw.
Programmiere also Deine gesamte Leseroutinen so, dass sie auch mit socket.recv(1) zurechtkommen, denn das ist die garantierte Nachrichtenlänge .
@Stollberg: Falls das bisher nicht klar geworden ist: Dein Programm hat bisher nur zufällig funktioniert, denn Du behandelst die Datenübertragung falsch. Auch bei Meldungen die kleiner als 8 KiB sind ist in keinster weiser garantiert das die bei einem `recv()` gelesen werden. Dein Programm ist also fehlerhaft.
@Stollberg: Du musst in einer Schleife so lange lesen bis eine komplette Message angekommen ist. Das musst Du der Message also irgendwie ansehen können. Entweder durch ein Endkennzeichen was nicht innerhalb der Message vorkommen darf, oder in dem Du am Anfang die Länge in einem festen Format übermittelst. Und Du musst beim Lesen auch darauf achten, dass der Anfang einer eventuellen Folge-Message auch schon gelesen werden kann und für das nächste mal Lesen gemerkt werden muss.
Am einfachsten lässt man sich vom `socket`-Objekt ein Datei-Objekt geben. Dann kann man nämlich `next()` und `read()`/`write()` verwenden, mit den Garantien die Datei-Objekte in Python geben. Also zum Beispiel das `read(n)` wirklich so lange blockiert bis entweder `n` Bytes gelesen wurden oder das Ende der Datei erreicht wurde. Letzteres ist bei `socket`-Verbindungen erreicht wenn die Gegenseite die Verbindung schliesst.
Am einfachsten lässt man sich vom `socket`-Objekt ein Datei-Objekt geben. Dann kann man nämlich `next()` und `read()`/`write()` verwenden, mit den Garantien die Datei-Objekte in Python geben. Also zum Beispiel das `read(n)` wirklich so lange blockiert bis entweder `n` Bytes gelesen wurden oder das Ende der Datei erreicht wurde. Letzteres ist bei `socket`-Verbindungen erreicht wenn die Gegenseite die Verbindung schliesst.