Socket / POP3 - Buffer Problem
-
Moin ... Thema Emails über Socket einlesen - via POP3:
... ... try { while (durchgang != neueemails + 1) { //Variablen zurücksetzen bigbuffer->Clear (bigbuffer, 0, bigbuffer->Length); bigbufferstring = ""; bytecount = 0; startindex = 0; index1 = 0; index2 = 0; emailbytes = 0; //Wie groß ist die nte Email? array<Byte>^ list = Encoding::Default->GetBytes ("LIST"+" "+durchgang+"\r\n"); s->Send ( list, SocketFlags::None); //Solange wie empfangene bytes nicht mehr null while ( bytecount < 1) { bytecount = s->Receive (bigbuffer); } bigbufferstring = Encoding::ASCII->GetString ( bigbuffer,0, bytecount ); startindex = bigbufferstring->IndexOf (durchgang.ToString ()) + 1; String^ hilfe = bigbufferstring->Substring (startindex, bigbufferstring->Length - startindex); emailbytes = Convert::ToInt64 (bigbufferstring->Substring (startindex, bigbufferstring->Length - startindex)); //Buffer säubern bigbuffer->Clear (bigbuffer, 0, bigbuffer->Length); //Holt die nte Mail vom Server array<Byte>^ retr = Encoding::ASCII->GetBytes ("RETR"+" "+durchgang+"\r\n"); s->Send ( retr, SocketFlags::None); while ( bytecount != emailbytes ) { bytecount = s->Receive ( bigbuffer , emailbytes, SocketFlags::None ); } emailtexte->Add ( Encoding::ASCII->GetString (bigbuffer, 0, bigbuffer->Length) ); durchgang++; } } catch ( Exception^ e) { };
Mein Problem hierbei sieht so aus: Das einlesen der ersten Email klappt einwandfrei. Jedoch fehlen meiner Meinung nach einige Bytes an Daten, welche erst im zweiten Durchlauf auftauchen und das weitere durchlaufen verhindern. Beim aufrufen von bspw. RETR fehlt mir also genauer gesagt meistens der abschließende "Punkt" - der ja das Ende der Email darstellen sollte.
Also dachte ich mir zunächst - der Buffer sei evtl. nicht groß genug oder die Abfrage sei falsch. Also versuchte ich dies für RETR so:
while ( bytecount < emailbytes + 1) { bytecount = s->Receive ( bigbuffer , emailbytes, SocketFlags::None ); }
.. was aber in einer Endlosschleife endet. Wo muss ich ansetzen ?
-
Moin,
ich habe das Protokoll jetzt nicht im Kopf ... aber eigentlich sollte alles geliefert werden ... entweder die Länge der Bytes bzw. wann die e-Mail zu Ende ist ... außerdem empfehle ich Dir ein vorhandenes Framework einzusetzen
emailtexte->Add ( Encoding::ASCII->GetString (bigbuffer, 0, bigbuffer->Length) );
nicht jede e-Mail ist in ASCII codiert ... außer Du machst das nur zu Übungszwecken
hand, mogel
-
Möchte hier nochmal ansezten, um Fehler zu vermeiden:
//Variablen zurücksetzen bigbuffer->Clear (bigbuffer, 0, bigbuffer->Length); bigbufferstring = ""; bytecount = 0; emailbytes = 0; array<Byte>^ retr = Encoding::ASCII->GetBytes ("RETR"+" "+durchgang+"\r\n"); s->Send ( retr, SocketFlags::None); //Statusmeldung (+OK o. -ERR + \r\n) do { bytecount = s->Receive ( bigbuffer , 5, SocketFlags::None); } while (bytecount != 5); //eigentliche Email bigbuffer->Clear (bigbuffer, 0, bigbuffer->Length); bytecount = 0; int bytepos = 0; int paket = s->Available; do { bytepos += s->Receive (bigbuffer, bytepos, paket, SocketFlags::None); paket = s->Available; } while (s->Available);
Wenn ich diesen Code Schritt für Schritt debugge, kommt es zum gewünschten Ergebnis. Setzte ich den Breakpoint jedoch hinter diesen Code - erhalte ich wieder nur Abgeschnittene Code Segmente. Irgendwie werde ich das Gefühl nicht los, dass der Code "zu schnell" durchläuft, und damit der interne Socket Buffer nicht schnell genug gefüllt wird. Kann das sein - oder sieht jemand den Übeltäter?
-
Hallo
Mit diesem Code schreibe ich die URL in eine ListBox, das funktioniert auch aber er schreibt sie mehrmals darein. Ich weiss nicht warum und ich möchte das er das nur einmal macht. Wie sage ich ihm das ?[code] listBox1->Items->Add(webBrowser1->Url);
[/code]
Vielen Dank im Voraus
-
Heinerich schrieb:
Hallo
Mit diesem Code schreibe ich die URL in eine ListBox, das funktioniert auch aber er schreibt sie mehrmals darein. Ich weiss nicht warum und ich möchte das er das nur einmal macht. Wie sage ich ihm das ?[code] listBox1->Items->Add(webBrowser1->Url);
[/code]
Vielen Dank im Voraus
Der Fehler liegt woanders. Der von dir gezeigte Code wird mit ziemlicher Sicherheit mehrmals aufgerufen. Zeig mal mehr.
-
bastel die mal eine State-Machine und lies aus dem Stream alles über einen String ein ... POP3 ist (afaik) nur Textbasiert ... also Zeile lesen und entsprechendes Event feuern
-
Momentan habe ich das ganze wie folgt gelöst, wobei auch hier ab und an der selbe Fehler auftritt. Jedoch wesentlich seltener:
array<Byte>^ retr = Encoding::ASCII->GetBytes ("RETR"+" "+durchgang+"\r\n"); s->Send ( retr, retr->Length, SocketFlags::None); bytecount = 0; int bytepos = 0; int paket = s->Available; do { do { bytepos += s->Receive (bigbuffer, bytepos, paket, SocketFlags::None); paket = s->Available; } while (s->Available); } while (s->Poll (600000, SelectMode::SelectRead) && s->Available);
Für eine sicherere Variante wäre ich weiterhin dankbar.