Il protocollo POP3Prima di iniziare a parlare di codice, dobbiamo analizzare il protocollo
POP3 nei dettagli.
POP3 (Post Office Protocol, versione 3) è stato definito con la
http://www.ietf.org/rfc/rfc1081.txt ">RFC 1081). Nonostante sia un protocollo "vecchio", è ancora utilizzato soprattutto per la sua semplicità.
Per poter vedere il protocollo in azione basta aprire un
Telnet alla porta
110 del nostro server di posta (telnet mail.mioserver.it 110). Il server ci risponderà con un messaggio di benvenuto. A questo punto dobbiamo autenticarci, per far ciò usiamo due comandi
USER e
PASS per inviare nome utente e password. Ora che siamo autenticati possiamo utilizzare tutti i comandi del POP3, ricordandoci che se un comando ha avuto esito positivo verrà rappresentato a terminale con un
"+OK" davanti al messaggio di risposta del server, al contrario se ha avuto esito negativo la risposta sarà
"ERR-".
Di seguito un elenco dei comandi
POP3:
Dopo questo elenco vediamo come sarebbe una sessione
POP3 da Telnet:
telnet mail.mioserver.it 110
+OK POP3 server ready
USER nomeUtente
+OK password required
PASS password
+OK 2 message
LIST
+OK
1 1942
2 3501
RETR 1
+OK
?? contenuto del primo messaggio
RETR 2
+OK
?? contenuto del secondo messaggio
DELE 2
+OK Message 2 deleted
QUIT
+OK Goodbye
Ma quando scrivi il codice?
Bene adesso che sappiamo come funziona il protocollo POP3 possiamo continuare, avevamo bisogno di queste tre nozioni perché con il nostro programma noi non faremo altro che aprire un socket alla porta 110 e inviare comandi del protocollo POP3.
Incominciamo allora a creare il nostro socket. Per crearlo dobbiamo importare il namespace System.Net
VB.NET
Imports System.Net
C#
using System.Net
A questo punto abbiamo bisogno di due oggetti un oggetto
System.Net.Sockets.NetworkStream e un oggetto
System.Net.Sockets.TcpClient, il primo è un oggetto che fornisce metodi per recuperare i dati forniti dal collegamento TCP che effettueremo con il secondo oggetto.
A questo punto non dobbiamo far altro che connetterci al sever di posta tramite socket sulla porta 110, per fare questo sfruttiamo il metodo
Connect() dell'oggetto
TcpClient, passando l'ndirizzo del server e la porta, dopo di che imposto l?oggetto
NetworkStream con la stringa di risposta del server
'Provo a connettermi
sckTcpClient.Connect(Server, 110)
'passo al socket stream i valori dello stream tcp
sckStreamSocket = sckTcpClient.GetStream()
Per controllare che la connessione sia avvenuta con successo devo controllare il messaggio che il server mi spedisce, ricordandomi che i primi tre caratteri sono
"+OK" se l'operazione è avvenuta. Per far questo prima devo leggere l'array di byte che mi invia il server, dopo di che tradurre questi in formato stringa e infine controllare i primi tre caratteri.
'dichiaro la matrice di byte
Dim byteServer(sckTcpClient.ReceiveBufferSize) As Byte
'leggo l'array di byte che mi restituisce il server
sckStream.Read(byteServer, 0, byteServer.Length)
'ricavo
myString += System.Text.Encoding.ASCII.GetString(byteServer)
'controllo le prime tre letter del messaggio
'se con +OK l'operazione è stata eseguita con successo
If Left(myString, 3) = "+OK" Then
Return True
Else
Return False
End If
D'ora in avanti ad ogni operazione controlleremo la risposta del server con i comandi appena utilizzati. Dopo che ci siamo connessi con successo dobbiamo autenticarci, quindi dobbiamo inviare al server un array di byte con i comandi di login e password, utilizzando il metodo
Write() della classe
NetworkStream che invia al server i nostri comandi.
'Codifico il comando in byte
byteCommand = System.Text.Encoding.ASCII.GetBytes("USER userName" + vbCrLf)
'Invio il comando al server
sckStreamSocket.Write(byteCommand, 0, byteCommand.Length)
una volta inviato il commando di login controlliamo la risposta del server eseguendo I controlli fatti anche per la connessione, se la risposta sarà positiva invieremo la password.
Ora controlliamo la dimensione della nostra casella di posta, utilizzando il comando
STAT.
'Codifico il comando in byte
byteCommand = System.Text.Encoding.ASCII.GetBytes("USER userName" + vbCrLf)
'Invio il comando al server
sckStreamSocket.Write(byteCommand, 0, byteCommand.Length)
'dichiaro la matrice di byte
Dim byteServer(sckTcpClient.ReceiveBufferSize) As Byte
'leggo l'array di byte che mi restituisce il server
sckStream.Read(byteServer, 0, byteServer.Length)
'ricavo la stringa
myString += System.Text.Encoding.ASCII.GetString(byteServer)
'faccio lo split del messaggio che è composto da +OK numeroMessaggi dimensioneTotale
Dim arrayStat as string()
arrayStat = myString.Split(" ")
'ricavo il numero di messaggi
intMessageCount = CType(arrayStat(1), Integer)
'ricavo la dimendione della casella di posta
intMailboxSize = CType(arrayStat(2), Integer)
A questo punto eseguire un qualsiasi comando pop risulta molto semplice, come quello per eliminare un messaggio:
'Codifico il comando in byte
byteCommand = System.Text.Encoding.ASCII.GetBytes("DELE " & intMessageNum + vbCrLf)
'Invio il comando al server
sckStreamSocket.Write(byteCommand, 0, byteCommand.Length)
Adesso che abbiamo l'elenco dei messaggi ricaviamo il testo del messaggio che voglio visualizzare utilizzando il comando
RETR, inviamo il comando come abbiamo fatto per il comando
LIST, il testo che il server ci restituirà sarà il testo del messaggio.
Come vedrete il testo comprenderà anche gli header del messaggio, per formattarli in modo corretto come un vero client di posta è necessario utilizzare le espressioni regolari. Prima di tutto devo identificare gli header dal resto del messaggio, con il comando
TOP riesco a ricavare l'header del messaggio che mi interessa.
Dopo aver ricavato gli headers del messaggio è possibile tramite l'uso delle
Regular Expressions recuperare parti degli headers come il campo From, To, Subject, ecc.