|
|||||
ソケット通信(System.Net.Sockets.TcpClient)によるメール送信(TLS有り)のサンプルです。 メールで送受信されているコマンドとレスポンスの参考になると思います。 SMTP AUTH認証にはAUTH LOGINとAUTH CRAM-MD5とAUTH PLAIN等がありますが、 AUTH PLAINのみ実装しています。 ※セキュリティで保護された接続(SMTP over SSL/TLSによる暗号化)について VB.NET標準のメール送信(System.Net.Mail.SmtpClient)はTLSに対応していますが、 SMTP over SSLに対応していないようです。 このサンプルは、TLSをソケット通信で実装したサンプルです。 簡単にメール送受信したい方は、こちらのDLLをオススメします。 メール送信/受信DLL(VB.NET/C#.NET) C#.NET版のサンプルソースはこちらです。 SMTP(TLS有り)でメール送信(TcpClientソケット通信)サンプル(C#.NET) メール関係のその他のサンプルはこちらです。 メール送信/メール受信サンプル(VBS/VBA) メール送信(SMTP認証/POP認証)のサンプル(VB.NET) SMTP(SSL無し)でメール送信(TcpClientソケット通信)サンプル(VB.NET) SMTP(SSL有り)でメール送信(TcpClientソケット通信)サンプル(VB.NET) POP3(SSL無し)でメール受信(TcpClientソケット通信)サンプル(VB.NET) POP3(SSL有り)でメール受信(TcpClientソケット通信)サンプル(VB.NET) IMAP(SSL無し)でメール受信(TcpClientソケット通信)サンプル(VB.NET) IMAP(SSL有り)でメール受信(TcpClientソケット通信)サンプル(VB.NET) メール関係のツールはこちらです。 指令メール実行 受信メールを監視しメールタイトルのキーワードに対応したプログラムを実行するツールです。 ファイル監視人 ファイルやフォルダの更新時にメッセージ表示またはメール送信するツールです。 フォルダ監視人 フォルダ内のファイル更新時に更新通知(差分メール等)、指定プログラム実行するツールです。 PC状況メール通知(PcEvMail) PC起動/PC終了/ログイン/ログアウト/ファイル更新時にメール通知/ログ出力するツールです。 ソケット通信関係のサンプルはこちらにもあります。 ソケット(TCP/IP)通信関係のサンプル ★フォーム(Form1.vb) Public Class Form1 Private cset As String = "ISO-2022-JP" Private serv As String = "smtp.xxx.com" Private port As Integer = 587 Private user As String = "user" Private pass As String = "pass" Private fadr As String = "送信元<fr@xxx.com>" Private tadr As String = "送信先<to@xxx.com>" Private subj As String = "タイトル" Private body As String = "本文" ' (TLS有り)SMTP AUTH PLAINでメール送信(TcpClientソケット通信)サンプル ' グーグル(smtp.gmail.com)でメール送信 Private Sub Button1_Click( _ ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' TcpClientソケット通信定義 Dim stream As Object Dim client As System.Net.Sockets.TcpClient ' SMTPサーバーに接続 client = New System.Net.Sockets.TcpClient client.Connect(serv, port) ' SSL無しの実装--------------------------------------------------------------- ' 通信開始(SSL無し) stream = client.GetStream() ' ---------------------------------------------------------------------------- ' SMTPサーバー接続時のレスポンス受信 Dim rstr As String rstr = StreamWriteAndRead(stream, "", cset) If rstr.StartsWith("2") = False Then Throw New Exception("エラー:" & rstr) End If ' EHLOの送信 Dim pcname As String = System.Net.Dns.GetHostName() rstr = StreamWriteAndRead(stream, "EHLO " & pcname & vbCrLf, cset) If rstr.StartsWith("2") = False Then Throw New Exception("エラー:" & rstr) End If ' TLSの実装------------------------------------------------------------------- ' STARTTLSの送信 rstr = StreamWriteAndRead(stream, "STARTTLS" & vbCrLf, cset) If rstr.StartsWith("2") = False Then Throw New Exception("エラー:" & rstr) End If ' SSLの開始 stream = New System.Net.Security.SslStream(client.GetStream()) stream.AuthenticateAsClient(serv) ' EHLOの送信 rstr = StreamWriteAndRead(stream, "EHLO " & pcname & vbCrLf, cset) If rstr.StartsWith("2") = False Then Throw New Exception("エラー:" & rstr) End If ' ---------------------------------------------------------------------------- ' SMTP AUTH 認証の実装-------------------------------------------------------- ' AUTH PLAINの送信(LOGINやCRAM-MD5はNonMailNet.dllをお試しください) rstr = StreamWriteAndRead(stream, "AUTH PLAIN" & vbCrLf, cset) If rstr.StartsWith("502") = False Then If rstr.StartsWith("3") = False Then Throw New Exception("エラー:" & rstr) End If ' ユーザIDとパスワードの生成 Dim upas As String = user & ControlChars.NullChar & _ user & ControlChars.NullChar & pass ' ユーザIDとパスワードの送信 rstr = StreamWriteAndRead(stream, Enc_Base64_1(upas, cset) & vbCrLf, cset) If rstr.StartsWith("2") = False Then Throw New Exception("エラー:" & rstr) End If End If ' ---------------------------------------------------------------------------- ' MAIL FROMの送信 fadr = fadr.Trim() Dim fa As String = New System.Net.Mail.MailAddress(fadr).Address rstr = StreamWriteAndRead(stream, "MAIL FROM:<" & fa & ">" & vbCrLf, cset) If rstr.StartsWith("2") = False Then Throw New Exception("エラー:" & rstr) End If ' RCPT TOの送信 tadr = tadr.Trim() Dim ta As String = New System.Net.Mail.MailAddress(tadr).Address rstr = StreamWriteAndRead(stream, "RCPT TO:<" & ta & ">" & vbCrLf, cset) If rstr.StartsWith("2") = False Then Throw New Exception("エラー:" & rstr) End If ' DATAの送信 rstr = StreamWriteAndRead(stream, "DATA" & vbCrLf, cset) If rstr.StartsWith("2") = False And rstr.StartsWith("3") = False Then Throw New Exception("エラー:" & rstr) End If ' 本文DATAの作成(From) Dim data As String = "" Dim frd As String = New System.Net.Mail.MailAddress(fadr).DisplayName data &= "From: " & Enc_Base64_2(frd, cset) & "<" & fa & ">" & vbCrLf ' 本文DATAの作成(To) Dim tod As String = New System.Net.Mail.MailAddress(tadr).DisplayName data &= "To: " & Enc_Base64_2(tod, cset) & "<" & ta & ">" & vbCrLf ' 本文DATAの作成(Subject) data &= "Subject: " & Enc_Base64_2(subj, cset) & vbCrLf ' 本文DATAの作成(MIME-Version) data &= "MIME-Version: 1.0" & vbCrLf ' 本文DATAの作成(Content-Type) -- 添付ファイル無しの時 -- data &= "Content-Type: text/plain; charset=""" & cset & """" & vbCrLf ' (参考)添付ファイル有りの時は(Content-Type: multipart/mixed; boundary="XXX") ' 本文DATAの作成(Content-Transfer-Encoding) data &= "Content-Transfer-Encoding: 7bit" & vbCrLf & vbCrLf ' 本文DATAの作成(本文) data &= body & vbCrLf ' 本文DATAの作成(.を..に変換) data = data.Replace(vbCrLf & "." & vbCrLf, vbCrLf & ".." & vbCrLf) ' 本文DATAの作成(.を付加) data &= vbCrLf & "." & vbCrLf ' 本文DATAの送信 rstr = StreamWriteAndRead(stream, data, cset) If rstr.StartsWith("2") = False Then Throw New Exception("エラー:" & rstr) End If ' QUITの送信 rstr = StreamWriteAndRead(stream, "QUIT" & vbCrLf, cset) If rstr.StartsWith("2") = False Then Throw New Exception("エラー:" & rstr) End If End Sub ''' <summary> ''' メールサーバとの送受信 ''' </summary> ''' <param name="stm">メールサーバ通信ストリーム</param> ''' <param name="req">リクエスト(コマンド)</param> ''' <param name="cst">文字コード</param> ''' <returns>レスポンス</returns> ''' <remarks></remarks> Private Function StreamWriteAndRead( _ ByVal stm As Object, _ ByVal req As String, _ ByVal cst As String) As String ' メールサーバへリクエスト送信 If req <> "" Then Dim sdat() As Byte sdat = System.Text.Encoding.GetEncoding(cst).GetBytes(req) stm.Write(sdat, 0, sdat.Length) stm.Flush() End If ' メールサーバからのレスポンス受信 Dim rstr As String = "" Dim rdat() As Byte ReDim rdat(1024 * 1024 - 1) Dim l As Integer = stm.Read(rdat, 0, rdat.Length) If l > 0 Then ReDim Preserve rdat(l - 1) rstr = System.Text.Encoding.GetEncoding(cst).GetString(rdat) Else Throw New Exception("Read Error.") End If ' レスポンス応答 Return rstr End Function ''' <summary> ''' 指定文字コードのBASE64エンコード ''' </summary> ''' <param name="str">オリジナル文字列</param> ''' <returns>エンコード結果文字列</returns> ''' <param name="cst">文字コード</param> ''' <remarks></remarks> Private Function Enc_Base64_1(ByVal str As String, ByVal cst As String) As String If str = "" Then Return "" Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding(cst) Return Convert.ToBase64String(enc.GetBytes(str)) End Function ''' <summary> ''' 指定文字コードのBASE64エンコード ''' </summary> ''' <param name="str">オリジナル文字列</param> ''' <param name="cst">文字コード</param> ''' <returns>エンコード結果文字列</returns> ''' <remarks>"=?ISO-2022-JP?B?"〜"?="フォーマット</remarks> Private Function Enc_Base64_2(ByVal str As String, ByVal cst As String) As String If str = "" Then Return "" Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding(cst) Return "=?" & cst & "?B?" & Convert.ToBase64String(enc.GetBytes(str)) & "?=" End Function End Class |