Probleme mit ReceiveNetworkData

Anfängerfragen zum Programmieren mit PureBasic.
ambientmusic
Beiträge: 3
Registriert: 02.01.2006 12:53

Probleme mit ReceiveNetworkData

Beitrag von ambientmusic »

Hallo,
habe jetzt schon seit einigen Tagen ein Problem mit ReceiveNetworkData. Ich schreibe gerade an einem Programm, welches POP3 Accounts abfragt und Mails abruft. Mit kleinen Mails ist das auch kein Problem, allerdings wenn die Dateien eine gewisse Größe erreichen (z. B. Dateianlagen) ist die Übertragung mittels ReceiveNetworkData nicht vollständig. Hab auch schon im Forum gesucht, allerdings funktionieren die Lösungsvorschläge nicht.

Hier mein Beispiel:

(zunächst wird anhand des pop3 list commands die größe der Mail ermittelt und in die variable groesse geschrieben)


Code: Alles auswählen

    *mail = AllocateMemory(groesse)
    SendNetworkString(ConnectionId,"RETR 1")
    ReceiveNetworkData(ConnectionId, *mail,Int(groesse) )
    OpenFile(1,"mail.txt")
    WriteString(PeekS(*mail))
    CloseFile(1)
Nach ausführen des Codes wird in die Datei nur ein Teil der empfangenen Mail geschrieben.
Hab das ganze auch schon mit einer While wend Schleife versucht, hat auch nicht funktioniert. Kann mir irgendjemand damit helfen? Hab mit Netzwerk in PB fast noch nichts gemacht.
Danke schon mal.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Hast du mal WriteData ausprobiert ?
Benutzeravatar
Laurin
Beiträge: 1639
Registriert: 23.09.2004 18:04
Wohnort: /dev/eth0

Beitrag von Laurin »

Code: Alles auswählen

    *mail = AllocateMemory(groesse)
    SendNetworkString(ConnectionId,"RETR 1")
    Empfangen = 0
    While Empfangen < groesse
        Delay(1)
        Empfangen + ReceiveNetworkData(ConnectionId, *mail + Empfangen, groesse - Empfangen)
    Wend
    OpenFile(1,"mail.txt")
    WriteString(PeekS(*mail))
    CloseFile(1) 
Das Problem ist, dass du den Receive-Befehl schon abfragt, bevor die gesamte eMail angekommen ist. Drum ist da jetzt eine Schleife drin, die solange läuft, bis alle Daten da sind.
Man muss aber aufpassen, dass daraus keine Endlosschleife wird (zB wenn wegen Störungen nicht alle Daten ankommen, dann wartet die Schleife ja ewig).
Now these points of data make a beautiful line.
And we're out of beta. We're releasing on time.
Team100
Beiträge: 104
Registriert: 13.09.2004 22:59

Beitrag von Team100 »

@Laurin

Vorsicht! :o

ReceiveNetworkData() liefert -1 zurück wenn die Abfrage fehlschlägt .....
(weil z.B. der Netzwerks-Empfangsbuffer noch leer ist wegen langsamer
Verbindung)

Die Endlosschleife ist vorprogrammiert... /:->

Cu Team100
Kompliziert kann es jeder lösen, aber das wirklich Geniale ist einfach.....
Benutzeravatar
Laurin
Beiträge: 1639
Registriert: 23.09.2004 18:04
Wohnort: /dev/eth0

Beitrag von Laurin »

Ich wußte, ich hab was vergessen /:->

Es muss sowieso noch eine zweite Abbruchbedingung rein (Timeout & dergleichen).
Now these points of data make a beautiful line.
And we're out of beta. We're releasing on time.
ambientmusic
Beiträge: 3
Registriert: 02.01.2006 12:53

Beitrag von ambientmusic »

@Laurin

Danke für die schnelle Antwort.

Der Code funktioniert so weit (bei kleinren Mails). Bei größeren Mails hab ich jetzt erneut ein Problem. Sobald ich auf den Speicherbereich mit PeekS(*mail) zugreifen will stürzt das Programm ab. Im Debug Mode wird invalid memory Access als Fehler angegeben.
Im konkreten Fall hab ich es mit einer jpg Datei die ca. 900 kbyte groß ist getestet. Dann hatte ich mit drei einzelnen kleineren Bildern <100 kbyte getestet und da war es kein Problem. Es ist doch eigentlich schon möglich eine Datei mit ca 900 kbyte in den Speicher zu lesen oder? Fällt Dir vielleicht dazu noch was ein? Wg. Timeout dürfte es eigentlich keine Probleme geben, da das Programm hier im Lan verwendet wird.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

> Sobald ich auf den Speicherbereich mit PeekS(*mail) zugreifen will stürzt
> das Programm ab.

PB hat (bis jetzt) immer noch Probleme mit der Adressierung von Strings,
die größer als 64 KB sind. Ein PeekS() auf einen Speicherbereich
durchzuführen, der als Ergebnis einen für PB zu grossen String
zurückliefert, ist also keine gute Idee.

Abhilfe:

* Anderen Lösungsweg verfolgen

oder: [c]DG_SetPBStringSize()[/c] aus den PBOSL verwenden

oder: Auf PB 4.0 warten ;-)

Grüße ... Kiffi
Team100
Beiträge: 104
Registriert: 13.09.2004 22:59

Beitrag von Team100 »

Im konkreten Fall hab ich es mit einer jpg Datei die ca. 900 kbyte groß ist getestet. Dann hatte ich mit drei einzelnen kleineren Bildern <100 kbyte getestet und da war es kein Problem. Es ist doch eigentlich schon möglich eine Datei mit ca 900 kbyte in den Speicher zu lesen oder? Fällt Dir vielleicht dazu noch was ein?
*.jpg Dateien solltest Du mit WriteString(PeekS(*mail)) überhaupt nicht
bearbeiten können, da beim ersten Hex00 im jpg das Ende des Strings erkannt
wird und der Rest dann verloren geht. :|

Besser WriteData(*mail, gesamtelaenge) verwenden ..... :wink:

In jedem Falle solltest Du auch prüfen, ob Dir AllocateMemory()
auch eine Adresse geliefert hat, wenn nicht (= 0), dann war Deine
Speicheranforderung zu groß.

Cu Team100
Kompliziert kann es jeder lösen, aber das wirklich Geniale ist einfach.....
ambientmusic
Beiträge: 3
Registriert: 02.01.2006 12:53

Beitrag von ambientmusic »

Danke Euch allen für die schnelle Hilfe, es funktioniert jetzt.

Ich schreib die Mails nicht mehr direkt in den Speicher, sondern erst in eine Temp Datei. Das Programm dürfte zwar etwas langsamer sein als mit der ersten Methode, aber dafür funktioniert es auch mit großen Mails ohne Probleme.

Grüße
Antworten