Smtp un Pop3 serveris

Kādu laiku jau nomoka doma, ka vajadzētu publicēt savus risinājumus Lattelecom IT olimpiādes uzdevumiem. Kaut vai tāpēc, lai topošajiem dalībniekiem būtu iespēja ne tikai redzēt, kādi uzdevumi bija jārisina agrāk, bet arī redzēt risinājumu piemērus, tādā veidā nedaudz izlīdzinot izredzes starp jaunajiem dalībniekiem un tiem, kas olimpiādē piedalās jau otro vai trešo gadu pēc kārtas.

Kā pirmo šādu piemēru izvēlējos 2009. gada fināla kārtas studentu grupas 1. dienas uzdevumu “S: SMTP/POP3 serveris”. Šāds uzdevums tika izvēlēts, jo SMTP un POP3 protokoli, lai arī mūžseni, ir vēl joprojām ļoti aktuāli, bet tajā pašā laikā ļoti triviāli, ja nav mērķis saprast e-pasta saturu, bet tikai to pārsūtīt tālāk.

Pirmais solis, šo uzdevumu pildot, ir atrast protokola aprakstus. Pirmā iespaida iegūšanai nekā labāka par Wikipedia nevar vēlēties – SMTP un POP3. Tālāk jau var pētīt precīzās specifikācijas, kurās būtu jābūt aprakstītām visām detaļām: RFC 5321 (SMTP) un RFC 1939 (POP3). Un, pats galvenais, jāver vaļā komandrinda un telnet, lai izmēģinātu ar roku pieslēgties kādam reālam serverim.

IT olimpiādē dalībniekiem bija 6,5 stundas, lai ar šo uzdevumu tiktu galā. Diemžēl tikai viena komanda (Tornado) iesniedza risinājumu, kas veiksmīgi tika galā ar e-pastu saņemšanu un atdošanu klienta programmatūrai. Tā kā man pašam ir acīmredzamas priekšrocības, kas radās, pašam izdomājot šo uzdevumu, risinājums tādā formā, kā tas redzams pievienotajā arhīvā, aizņēma apmēram 2,5 līdz 3 stundas.

SimpleMail risinājums: SimpleMail.zip  (44kb). Risinājums gan netiek darbināts kā serviss, bet gan kā komandrindas aplikācija, taču tas darīts, lai vienkāršotu tā izmēģināšanu. Tāpat nav arī realizētas papildus iespējas, par kurām olimpiādē vienojās dalībnieki. Tornado komandas risinājumā vairākas papildus iespējas bija realizētas.

Kā darbināt serveri – jāpalaiž SimpleMail.exe un sava klienta programmatūra jākonfigurē, lai izmantotu 127.0.0.1:25 un 127.0.0.1:110. Jāņem vērā, ka localhost vārda izmantošana varētu nestrādāt, ja e-pasta programmatūra atbalsta IPv6 – tādā gadījumā tā mēģinās slēgties pie adreses ::1, kuru serveris var neatbalstīt. Serveris pieņem e-pastus visiem adresātiem, lai piekļūtu pie saņemtajām e-pasta adresēm, kā POP3 lietotāja vārds un parole jānorāda šī e-pasta adrese.

Risinājumā ir ļoti daudz punktu, kurus vajadzētu pielabot, taču galveno virzienu, kādā strādāt, tas labi parāda.

Pamata servera darbību nodrošina klase BaseServer. Izveidojot šo objektu, tas automātiski palaiž TCP serveri (izmantojot TcpListener klasi) un jaunu pavedienu (Thread), kurš gaidīs, kad pie servera kāds pieslēgsies. Svarīga nianse – šis pavediens pats jauno pieslēgumu neapstrādā. Tā vietā tas izmanto metodi QueueUserWorkItem, kas nodrošina spēju apstrādāt vairākus pieslēgumus reizē. QueueUserWorkItem izmanto .NET iebūvētu slodzes dalīšanas mehānismu, kas ļauj reģistrēt vairākas darba vienības, kuras tiek izpildītas viena pēc otras, nodrošinot, ka paralēli netiek izpildīti vairāk uzdevumu kā dators spēj veiksmīgi darbināt.

BaseServer nodrošina pamata funkcionalitāti – tas no pieslēguma nolasa komandu (gan SMTP, gan POP3 komanda tiek nodota vienā atsevišķā teksta rindā) un nodod šo komandu apstrādei IProcessor interfeisam. Klases, kas implementē šo interfeisu (SmtpProcessor un Pop3Processor), nodrošina katras konkrētas komandas izpildi, kā arī saglabā pieslēguma stāvokļa informāciju (lietotāja vārdi, e-pasta saņēmēji utt.).

Šādi sadalīts kods ļauj izvairīties no koda dublēšanas un nodalīt tīkla savienojuma apstrādi no SMTP vai POP3 komandu apstrādes. Izmantotais mehānisms arī demonstrē salīdzinoši elegantu veidu, kā nodrošināt salīdzinoši augstu veiktspēju, kur viens pieslēgums nebloķē citus.

Comments are closed