Seite 1 von 1

Abfrage eines Imap Servers?

Verfasst: 27. Dezember 2008 13:25
von Treehouse
Hallo zusammen,

ich wollte ein kleines Programm schreiben was mir anzeigt ob neue Emails vorliegen. Ich weiß sowas gibts schon hundertfach aber ich wollte mir halt mal mein eigens schreiben, dies soll auch zur Übung dienen.

So nun zu meinem Problem. Ich habe folgenden Code mal dazu geschrieben:

Code: Alles auswählen

#include "gmail.h"

Gmail::Gmail()
{
	connect(&socket, SIGNAL(encrypted()), this, SLOT(ready()));
	connect(&socket, SIGNAL(readyRead()), this, SLOT(read()));
	socket.connectToHostEncrypted("imap.gmail.com", 993);
	
	
}

Gmail::~Gmail()
{

}

void Gmail::ready()
{
}

void Gmail::read()
{
		qDebug() << socket.readAll();		
}

void Gmail::login()
{
	socket.write(". LOGIN UserName Passwordn");
}

void Gmail::show()
{
               socket.write(". status INBOX (messages)\n");
}
Dies ist wirklich sehr grob geschrieben zunächst ich wollte erst mal mir den Ablauf klar machen. Das Problem ist jetzt, daß das login super funktioniert aber wenn ich dann noch ein show in der main Funktion aufrufe scheint dies aufgrund des Application Threads zu früh ausgeführt zu werden. Es sollte eigentlich so ablaufen das nach jedem Befehl gewartet wird das alles vom Server gelesen wurde und dann soll der nächste Befehl erst abgeschickt werden. Kann mir von euch jemand vielleicht sagen wie man das umsetzt. Ich habe schon mit der "waitForReadyRead" Funktion experimentiert aber leider hat das nicht so geklappt wie ich mir das vorgestellt habe. Ich wäre für eine kleine Hilfe sehr dankbar.

Gruß

Treehouse

Verfasst: 27. Dezember 2008 14:40
von upsala
Wo wertest du eigentlich die Rückgabewerte vom Server aus? Solange der Server nicht geantwortet hat, brauchst du ihm gar nichts schicken...

Verfasst: 27. Dezember 2008 14:50
von upsala
Als Beispiel:

Code: Alles auswählen

void Imap::readyRead() {
	QString result(m_socket->readAll());
	qDebug() << result;

	if (state==0 && result.startsWith("* OK")) {
		m_socket->write(". LOGIN user pwd\n");
		state=1;
	}

	if (state==1 && result.startsWith(". OK")) {
		m_socket->write(". SELECT INBOX\n");
		state=2;
	}

	if (state==2 && result.contains("RECENT")) {
		m_socket->write(". LOGOUT\n");
		qDebug() << result;
		m_socket->close();
		state=0;
	}
}

Verfasst: 27. Dezember 2008 15:02
von Treehouse
Ahh alles klar das ist auch eine Möglichkeit vielen Dank. Ich habe das jetzt so gemacht (Code ist unten) das klappt auch super. Alles was mit abfangen von Fehlern usw zu tun hat kommt noch alles ich sag ja das war ganz grob umrissen was ich versucht habe.

i

Code: Alles auswählen

nclude "gmail.h"

Gmail::Gmail()
{
	connect(&socket, SIGNAL(encrypted()), this, SLOT(ready()));
	connect(&socket, SIGNAL(readyRead()), this, SLOT(read()));
	socket.connectToHostEncrypted("imap.gmail.com", 993);
	
	
}

Gmail::~Gmail()
{

}

void Gmail::ready()
{
}

void Gmail::read()
{
 
   socket.waitForReadyRead(500); 
   while(socket.bytesAvailable()>0){ 
      message = socket.readAll(); 
      socket.waitForReadyRead(500); 
   }	
}

void Gmail::login()
{
	socket.write(". LOGIN username password\n");
	socket.waitForReadyRead(3000);
	qDebug() << message << endl;
	message.clear();	
}

void Gmail::show()
{
	socket.write(". list \"\" \"*\"\r\n");
	socket.waitForReadyRead(3000);
	qDebug() << message << endl;
	message.clear();	

}

Verfasst: 27. Dezember 2008 15:28
von upsala
Warum waitForReadyRead, wenn du eh schon im readyRead-Slot bist?

Verfasst: 27. Dezember 2008 21:36
von Treehouse
Nehm ich das raus funktioniert es nicht mehr, weil wie ich oben beschrieben habe ja die Funktion show zu schnell aufgerufen wird dann ist aber der Socket noch gar nicht verbunden. Ich denke das hängt mit dem Application Thread zusammen, aber da bin ich mir nicht sicher.

Verfasst: 27. Dezember 2008 22:07
von upsala
Soll ich meine Antworten wieder rauslöschen, oder willst du sie dir noch einmal durchlesen?

Verfasst: 27. Dezember 2008 22:14
von Treehouse
Ahh ich verstehe was du meinst..... Sorry!

Verfasst: 27. Dezember 2008 23:24
von Treehouse
Ich habe es jetzt mal genauso gemacht wie du es beschrieben hast. Aber leider geht es nicht wenn ich in deinem Code keine "waits" einbaue klappt es nicht.

Verfasst: 28. Dezember 2008 11:44
von solarix
Treehouse hat geschrieben:... klappt es nicht
Das ist keine Fehlerbeschreibung. Schreibe jeweils präzise, was du erwartest und was du bekommst (qDebug() - Ausgaben). In deinem Fall wird's wohl so sein, dass das erwartete Datenpaket etwas grösser ist und daher mehrere "readyRead()"-Signals ausgelöst werden. TCP ist grundsätzlich als "Stream" zu betrachten, was bedeutet, dass du solange davon lesen musst, bis das ganze erwartete Datenpaket angekommen ist... sowas wie:

Code: Alles auswählen

slotReadyRead()
{
  paket += leseAlleNeuenDaten()
  if (testDesPaketsAufVollständigkeit(paket) == true)
  {
     machWas(paket)
     state = xy  // siehe StateMachine von upsala
     leerePaket(paket)
  }
  else
    qDebug() << "Daten unvollstaendig.. warte auf weitere daten"
}

Verfasst: 28. Dezember 2008 12:43
von dontinelli
Ich bin daran, einen Mail-client für verschlüsselten/signierten Mailverkehr zu programmieren. Momentan ist nur Pop/Smtp unterstützt, du kannst aber gerne mal schauen, wie wir es dort gemacht haben. Und wenn du Lust hast, kanntst du uns natürlich auch gerate im Bereich IMAP unterstützen...
http://sourceforge.net/projects/nlcreator/