Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Inviare email in Visual C++

Scrivere una semplice applicazione in c++ per l'invio di messaggi email tramite il protocollo SMTP, utilizzando il framework .NET
Scrivere una semplice applicazione in c++ per l'invio di messaggi email tramite il protocollo SMTP, utilizzando il framework .NET
Link copiato negli appunti

In questo articolo vedremo come scrivere un'applicazione in C++ per l'invio di messaggi email tramite il protocollo SMTP, utilizzando il framework .NET.

In particolare vedremo come utilizzare le classi:

  • MailMessage per rappresentare e comporre un messaggio di posta elettronica
  • SmtpClient per effettuare l'invio dei messaggi

che fanno parte del namespace System::Net::Mail. I messaggi creati verranno spediti tramite il metodo asincrono SendAsync e controlleremo che essi siano stati effettivamente spediti prima di chiudere l'applicazione e rilasciare le risorse allocate.

Iniziamo a costruire la nostra applicazione con Visual C++ (con Visual Studio o Visual C++ Express). Anzitutto creiamo una nuova applicazione CLR, per semplificare, una Applicazione console CLR.

Figura 1. Creare una Applicazione console CLR
Creare una Applicazione console CLR

Fatto questo procediamo subito all'importazione delle librerie di cui avremo bisogno. I Namespace sono:

using namespace System;
using namespace System::Net;
using namespace System::Net::Mail;

Come abbiamo anticipato, istanziando la classe MailMessage possiamo costruire un messaggio che potremo trasmettere successivamente ad un server SMTP. Vediamo subito come specificare mittente, destinatario e contenuto, grazie alle proprietà di MailMessage:

// Specifichiamo il mittente (FROM)
// Creiamo un indirizzo email che includa caratteri UTF8
MailAddress^ from = gcnew MailAddress("paolinopaperino@miaemail.com",
"Paolino " + (wchar_t)0xD8 + " Paperino", System::Text::Encoding::UTF8);
// Impostiamo il destinatario ovvero il TO.
MailAddress^ to = gcnew MailAddress("paperina@tuaemail.com");
// Creiamo il contenuto del messaggio utilizzando la classe MailMessage.
MailMessage^ message = gcnew MailMessage(from, to);
message->Body = "Ciao Mondo - questo è un semplice test per invio email " +
" da un applicazione scritta in c++. ";
// Includiamo alcuni caratteri non-ASCII nel corpo ed anche nel subject
String^ someArrows = gcnew String(gcnew array<wchar_t>{L'u2190', L'u2191', L'u2192', L'u2193'});
message->Body += Environment::NewLine + someArrows;
message->BodyEncoding = System::Text::Encoding::UTF8;
message->Subject = "Prova invio email" + someArrows;
message->SubjectEncoding = System::Text::Encoding::UTF8;

Ora vediamo come inviare le nostre email grazie alla classe SmtpClient, usando il protocollo SMTP. Per l'invio della Mail bisogna che venga specificato il nome dell' SMTP server (per esempio: smtp.yahoo.it).

// Come argomento da linea di commando viene passato il nome dell' SMTP server.
SmtpClient^ client = gcnew SmtpClient(args[1]);

Invio sincrono e asincrono

A questo punto abbiamo tutto ciò che ci serve per poter inviare email, non ci resta che invocare il comando di invio. A tal proposito esistono due metodi uno sincrono ed uno asincrono.

  • Il metodo Send, blocca l'esecuzione dell'applicazione finché l'email non è stata inviata
  • Il metodo SendAsync, invece permette al thread di continuare l'esecuzione mentre l'email viene spedita

SendAsync può essere utilizzato in maniera identica a come si potrebbe utilizzare Send, l'istanza di SmtpClient richiamerà eventuali sottoscrittori dell'evento SendCompleted, per controllare se l'email è stata inviata o meno.

L'operazione asincrona non blocca l'esecuzione dell'applicazione e potrebbe capitare l'inconveniente di chiudere l'applicazione prima che l'email sia stata spedita, cancellando pertanto la trasmissione del messaggio. Per evitare ciò dobbiamo riferirci all'evento SendCompleted, e quindi aggiungere un delegato SendCompletedEventHandler all'evento.

Il delegato SendCompletedEventHandler deve referenziare un metodo di callback che gestisce la notifica dell'evento SendCompleted. Infine per poter cancellare una trasmissione email asincrona si utilizza il metodo SendAsyncCancel.

client->SendCompleted += gcnew SendCompletedEventHandler(SendCompletedCallback);
String^ userState = "Prova 1";
client->SendAsync(message, userState);
Console::WriteLine("Invio del messaggio... premi il tasto 'c' se vuoi cancellare la mail. Premi un tasto qualsiasi per uscire.");
String^ risp = Console::ReadLine();
// Se l'utnete preme il tasto c e cancella l'invio e
// l'email non è stata ancora inviata,
// allora viene cancellata l'operazione in stato di pending
if (risp->ToLower()->StartsWith("c") && mailSent == false)
{
client->SendAsyncCancel();
}

La connessione stabilita per l'istanza della classe SmtpClient al server SMTP può essere riutilizzata, ad esempio se vogliamo che la nostra applicazione debba inviare più messaggi al server SMTP stesso. Il ristabilire una connessione al server SMTP stesso per ogni messaggio quando si invia una grande quantità di posta elettronica può avere un impatto altamente significativo sulle prestazioni.

Ci sono una serie di applicazioni ad alto volume di traffico, per esempio applicazioni che inviano email per gli aggiornamenti, distribuzioni newsletter, o avvisi. Anche molte applicazioni client di posta elettronica supportano un modo off-line dove gli utenti possono comporre messaggi di posta elettronica che vengono inviati in un secondo momento, quando una connessione al server SMTP è presente.

La classe SmtpClient raggruppa tutte le connessioni SMTP in modo da evitare il sovraccarico di ristabilire una connessione allo stesso server per ogni messaggio. Un'applicazione può riutilizzare lo stesso oggetto SmtpClient ed inviare differenti messaggi di posta elettronica allo stesso server SMTP ed anche ad altri server SMTP. Di conseguenza, non vi è alcun modo per determinare quando un'applicazione ha finito di utilizzare l'oggetto SmtpClient e quindi terminare l'oggetto stesso.

Quando una sessione SMTP ha finito di trasmettere ed il client desidera terminare la connessione, bisogna che sia il client stesso ad inviare un messaggio di QUIT al server per indicare che non ha più messaggi da inviare. Ciò consente al server di liberare le risorse associate con la connessione dal client ed elaborare i messaggi che li sono stati trasmessi.

La classe SmtpClient non possiede un metodo Finalize, quindi per poter liberare le risorse allocate bisogna invocare esplicitamente il metodo Dispose. Dispose scorre tutti i collegamenti stabiliti al server SMTP specificato nella proprietà Host e invia un messaggio QUIT seguito dal terminatore di connessione TCP.

È buona norma chiamare sempre il metodo Dispose quando si è terminato di utilizzare la classe SmtpClient per non tenere bloccate risorse ormai non più necessarie, ma Dispose rilascia l' SmtpClient in uno stato inutilizzabile, quindi, dopo averlo invocato, è necessario rilasciare tutti i riferimenti a SmtpClient in modo che il Garbage Collector possa recuperare la memoria che esso occupava.

// Rilascio delle risorse e recupero della memoria.
delete message;
client = nullptr;

Il codice completo dell'esempio è nell'allegato e può essere visualizzato qui.

Ti consigliamo anche