Ú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 Sub SendCommand(ByVal ns As NetworkStream, ByVal command As String)
Dim s As String = command + ControlChars.Cr + ControlChars.Lf
Dim ba As [Byte]() = Encoding.ASCII.GetBytes(s.ToCharArray())
ns.Write(ba, 0, ba.Length)
listBox1.Items.Add(s)
End Sub
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 Function ReadAnswer(ByVal ns As NetworkStream) As String
Dim sr As New StreamReader(ns)
Return sr.ReadLine()
End Function 'ReadAnswer
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öbbsoros lesz, így itt most nem használhatjuk a ReadAnswer függvényünket.
Private Sub listBox2_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles listBox2.SelectedIndexChanged
SendCommand(ns, "RETR " + (listBox2.SelectedIndex + 1).ToString())
Dim sr As New StreamReader(ns)
A többsoros 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öbbsoros választ egy olyan sor zárja, 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 Then
textBox4.Text = s
Exit Do
Else
If s.IndexOf("+OK") = -1 Then
textBox4.Text += s + ControlChars.Cr + ControlChars.Lf
End If
End If
Loop 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 Sub button4_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button4.Click
Dim sw As New StreamWriter(Application.StartupPath + "\" + DateTime.Now.ToString("yyyyMMdd") + "_" + (listBox2.SelectedIndex + 1).ToString() + ".eml", True)
sw.WriteLine(textBox4.Text)
sw.Close()
End Sub