Újságunk múlt heti számában megjelent „Új e-mail-ek érkezésének ellenőrzése az Exchange szerveren keresztül” című cikkben leírtak alapján az ottani alkalmazást fejlesztjük tovább annak érdekében, hogy most ne csak a beérkezett e-mail-ek számát tudjuk meghatározni, hanem az e-mail-ek tartalmához is hozzá tudjunk férni.

Mivel e példában nem tárgyaljuk újra az Exchange szerverrel történő a TCP-n keresztüli kapcsolatfelvételt, így a fent említett cikk ismerete szükséges lesz a mostani megértéséhez.
Első lépésként készítünk két függvényt, melynek segítségével könnyedén küldhetünk POP3 utasításokat az Exchange szervernek, illetve kiolvashatjuk a kapott válaszokat.
A SendCommand függvényünk két paramétert vár: a ns paraméterbe kell megadnunk a már megnyitott hálózati adatfolyamot leíró NetworkStream osztályt, míg a command paraméterbe kerül az átadandó POP3 utasítás.
Mivel minden utasítást egy sorvége jel kell hogy zárjon, így ezt minden esetben hozzáadjuk a command paraméter értékéhez. Ezt követően elvégezzük a sztring bájttömbbé való konvertálását, majd az adatküldést.
Végül a folyamat nyomon követésének érdekében a listBox1-be írjuk az aktuálisan elküldött parancsot.
private void SendCommand(NetworkStream ns, string command)
{
string s = command + "\r\n";
Byte[] ba = Encoding.ASCII.GetBytes(s.ToCharArray());
ns.Write(ba, 0, ba.Length);
listBox1.Items.Add(s);
}
A ReadAnswer függvény arra szolgál, hogy a paraméterként megadott adatfolyamból kiolvassa az elküldött parancsra adott választ. Ez a függvény csak egysoros válaszok kezelésére képes. Majd látni fogjuk, hogy éppen ezért ezt nem tudjuk minden esetben használni.
private string ReadAnswer(NetworkStream ns)
{
StreamReader sr = new StreamReader(ns);
return sr.ReadLine();
}
A TCP kapcsolat létrehozása és a POP3-as bejelentkezés után a listBox2-be felsoroljuk a még le nem töltött e-mail-ek sorszámát. Ezek után egy-egy e-mail-t úgy tudunk a szerverről letölteni, hogy rákattintunk a listBox2 adott elemére. Ekkor jön létre a SelectedIndexChanged esemény.
Ekkor kell küldenünk a mail szervernek egy RETR x utasítást, ahol az x a leöltendő e-mail sorszáma, melyet most nyilván a listBox-ból veszünk.
A RETR parancsra válaszként magát az e-mail-t kapjuk meg. Mivel ez valószínűleg több soros lesz, így itt most nem használhatjuk a ReadAnswer függvényünket.
private void listBox2_SelectedIndexChanged(object sender, System.EventArgs e)
{
SendCommand(ns, "RETR "+(listBox2.SelectedIndex+1).ToString());
StreamReader sr = new StreamReader(ns);
A több soros válasz első sora kétféleképpen kezdődhet: vagy +OK, vagy -ERR karakterekkel. +OK esetén hiba nem történt és a további sorokban az e-mail-t kapjuk meg. -ERR esetén hiba történt. A több soros választ egy olyan sor fogja zárni, mely egyetlen pont karaktert tartalmaz. Ezt felhasználva, ha nincs hiba, futtathatunk egy olyan do - while ciklust, mely addig olvassa a sorokat, amíg pontot nem talál. A kiolvasott sorokat a textBox4-be tároljuk el.
do
{
s = sr.ReadLine();
if (s.IndexOf("-ERR")==0)
{
textBox4.Text = s;
break;
}
else
{
if (s.IndexOf("+OK")==-1)
{
textBox4.Text += s + "\r\n";
}
}
}
while(s!=".");
}
Az e-mail kiolvasása után annak teljes tartalma a textBox4-be kerül. Ez magában foglalja az e-mail fejlécét, törzsét és esetleges állomány mellékleteit is. A felhasználó számára ez a mail így nehézkesen olvasható csak, ezért készítsünk egy olyan lehetőséget, hogy a textBox4 tartalmát lementhessük egy .EML állományba, melyet egy Outlook Express-el könnyedén elolvashatunk. Ehhez nincs más teendőnk, mint hogy a textBox4 tartalmát egy szöveges állományba mentsük, melynek .EML a kiterjesztése.
private void button4_Click(object sender, System.EventArgs e)
{
StreamWriter sw = new StreamWriter(Application.StartupPath+"\\"+DateTime.Now.ToString("yyyyMMdd")+"_"+(listBox2.SelectedIndex+1).ToString()+".eml", true);
sw.WriteLine(textBox4.Text);
sw.Close();
}