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.


Anmelden zum Antworten