Abfrage eines Imap Servers?

Alles rund um die Programmierung mit Qt
Antworten
Treehouse
Beiträge: 100
Registriert: 18. Juni 2007 10:21

Abfrage eines Imap Servers?

Beitrag 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
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Wo wertest du eigentlich die Rückgabewerte vom Server aus? Solange der Server nicht geantwortet hat, brauchst du ihm gar nichts schicken...
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag 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;
	}
}
Treehouse
Beiträge: 100
Registriert: 18. Juni 2007 10:21

Beitrag 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();	

}
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Warum waitForReadyRead, wenn du eh schon im readyRead-Slot bist?
Treehouse
Beiträge: 100
Registriert: 18. Juni 2007 10:21

Beitrag 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.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Soll ich meine Antworten wieder rauslöschen, oder willst du sie dir noch einmal durchlesen?
Treehouse
Beiträge: 100
Registriert: 18. Juni 2007 10:21

Beitrag von Treehouse »

Ahh ich verstehe was du meinst..... Sorry!
Treehouse
Beiträge: 100
Registriert: 18. Juni 2007 10:21

Beitrag 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.
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag 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"
}
dontinelli
Beiträge: 146
Registriert: 22. September 2006 20:53

Beitrag 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/
Antworten