┏第52号━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ .NETプログラミング研究 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
──<メニュー>───────────────────────
■.NET質問箱
・ポート番号を指定してSMTPでメールを送るには?
・SMTP認証でメールを送信するには?
Socketを使ってSMTPでメールを送るには?
───────────────────────────────
───────────────────────────────
■.NET質問箱
───────────────────────────────
「.NET質問箱」では、「どぼん!のプログラミング掲示板」に書き込
まれた.NETプログラミングに関する投稿を基に、さらに考察を加え、
Q&A形式にまとめて紹介します。
[URL]どぼん!のプログラミング掲示板
http://dobon.net/vb/bbs.html
───────────────────────────────
●ポート番号を指定してSMTPでメールを送るには?
【質問】
System.Web.Mail.SmtpMailクラスでメールを送信する時、25以外のポー
ト番号を指定することができないようです。25以外のポート番号を指
定してメールを送信するには、どうしたらよいのでしょうか?
【回答】
.NET Framework 1.1では、MailMessageクラスにFieldsプロパティが
加わり、これを使うことにより、CDOのフィールドにアクセスできる
ようになりました。これを使ってCDOのsmtpserverportフィールドを
変更すれば、System.Web.Mail.SmtpMailクラスでもポート番号を指定
してメールを送信することができます。
‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
System.Web.Mail.MailMessage mail = new System.Web.Mail.MailMessage();
//From
mail.From = "xxx@xxx.xxx";
//To
mail.To = "xxx@xxx.xxx";
//Subject
mail.Subject = "テスト";
//本文
mail.Body = "これはテストです。";
//ポート番号を指定する
mail.Fields[
"http://schemas.microsoft.com/cdo/configuration/smtpserverport"]
= 25;
System.Web.Mail.SmtpMail.SmtpServer = "xxx.xxx.xxx";
//メールを送信
System.Web.Mail.SmtpMail.Send(mail);
‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
Dim mail As New System.Web.Mail.MailMessage
'From
mail.From = "xxx@xxx.xxx"
'To
mail.To = "xxx@xxx.xxx"
'Subject
mail.Subject = "テスト"
'本文
mail.Body = "これはテストです。"
'ポート番号を指定する
mail.Fields.Item( _
"http://schemas.microsoft.com/cdo/configuration/smtpserverport") _
= 25
'SMTPサーバーを指定
System.Web.Mail.SmtpMail.SmtpServer = "xxx.xxx.xxx"
'メールを送信
System.Web.Mail.SmtpMail.Send(mail)
‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
参考:
[URL]The Code Project - SMTP Authentication using System.Web.
Mail (CDOSYS)
http://www.codeproject.com/dotnet/SystemWeb_Mail_SMTP_AUTH.asp
[URL]CDO for Windows 2000 http://schemas.microsoft.com/cdo
/configuration/ Namespace
http://msdn.microsoft.com/library/en-us/cdosys/html/_cdosys_schema_configuration.asp
.NET Framework 1.0を使用している場合は、残念ながらこのように
MailMessageクラスのFieldsプロパティを使うことが出来ません。し
かし、.NET Framework 1.0でもCDOを使用することは可能です。次に
CDOを使ってメールを送信するサンプルを紹介しましょう。遅延バイ
ンディングを行っているため、ちょっと複雑になっています。
‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
Type t = Type.GetTypeFromProgID("CDO.Message");
object cdo = Activator.CreateInstance(t);
t.InvokeMember("From",
System.Reflection.BindingFlags.SetProperty,
null, cdo, new object[] {"xxx@xxx.xxx"});
t.InvokeMember("To",
System.Reflection.BindingFlags.SetProperty,
null, cdo, new object[] {"xxx@xxx.xxx"});
t.InvokeMember("Subject",
System.Reflection.BindingFlags.SetProperty,
null, cdo, new object[] {"テスト"});
t.InvokeMember("Textbody",
System.Reflection.BindingFlags.SetProperty,
null, cdo, new object[] {"これはテストです!!"});
object conf = t.InvokeMember("Configuration",
System.Reflection.BindingFlags.GetProperty,
null, cdo, null);
object fields = t.InvokeMember("Fields",
System.Reflection.BindingFlags.GetProperty,
null, conf, null);
t.InvokeMember("Item",
System.Reflection.BindingFlags.SetProperty,
null, fields,
new object[] {
"http://schemas.microsoft.com/cdo/configuration/sendusing",
2});
//SMTPサーバーを指定する
t.InvokeMember("Item",
System.Reflection.BindingFlags.SetProperty,
null, fields,
new object[] {
"http://schemas.microsoft.com/cdo/configuration/smtpserver",
"xxx.xxx.xxx"});
//ポート番号を指定する
t.InvokeMember("Item",
System.Reflection.BindingFlags.SetProperty,
null, fields,
new object[] {
"http://schemas.microsoft.com/cdo/configuration/smtpserverport",
25});
t.InvokeMember("Update",
System.Reflection.BindingFlags.InvokeMethod,
null, fields,
new object[] {});
//送信する
t.InvokeMember("Send",
System.Reflection.BindingFlags.InvokeMethod,
null, cdo,
new object[] {});
‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
Dim t As Type = Type.GetTypeFromProgID("CDO.Message")
Dim cdo As Object = Activator.CreateInstance(t)
t.InvokeMember("From", _
System.Reflection.BindingFlags.SetProperty, _
Nothing, cdo, New Object() {"xxx@xxx.xxx"})
t.InvokeMember("To", _
System.Reflection.BindingFlags.SetProperty, _
Nothing, cdo, New Object() {"xxx@xxx.xxx"})
t.InvokeMember("Subject", _
System.Reflection.BindingFlags.SetProperty, _
Nothing, cdo, New Object() {"テスト"})
t.InvokeMember("Textbody", _
System.Reflection.BindingFlags.SetProperty, _
Nothing, cdo, New Object() {"これはテストです!!"})
Dim conf As Object = t.InvokeMember("Configuration", _
System.Reflection.BindingFlags.GetProperty, _
Nothing, cdo, Nothing)
Dim fields As Object = t.InvokeMember("Fields", _
System.Reflection.BindingFlags.GetProperty, _
Nothing, conf, Nothing)
t.InvokeMember("Item", _
System.Reflection.BindingFlags.SetProperty, _
Nothing, fields, New Object() { _
"http://schemas.microsoft.com/cdo/configuration/sendusing", _
2})
'SMTPサーバーを指定する
t.InvokeMember("Item", _
System.Reflection.BindingFlags.SetProperty, _
Nothing, fields, New Object() { _
"http://schemas.microsoft.com/cdo/configuration/smtpserver", _
"xxx.xxx.xxx"})
'ポート番号を指定する
t.InvokeMember("Item", _
System.Reflection.BindingFlags.SetProperty, _
Nothing, fields, New Object() { _
"http://schemas.microsoft.com/cdo/configuration/smtpserverport", _
25})
t.InvokeMember("Update", _
System.Reflection.BindingFlags.InvokeMethod, _
Nothing, fields, New Object() {})
'送信する
t.InvokeMember("Send", _
System.Reflection.BindingFlags.InvokeMethod, _
Nothing, cdo, New Object() {})
‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
CDOを使えない、あるいは使いたくないという場合は、自分でコード
を書くか、誰かが作ったコンポーネントやクラスを使わせてもらうか
ということになるでしょう。例えば、Tatsuo Babaさんの「BASP21
DLL」を使わせていただくのも有効な方法の一つです。
[URL]Baba Centerfolds
http://www.hi-ho.ne.jp/babaq/index.html
自分でコードを書くということになると、ソケットを使用することに
なります。この場合はもちろん、SMTPやMIMEに関する知識が必要です。
SMTPについてRFCではRFC821で、さらにESMTPについてはRFC1869など
で定義されています。
[URL]SIMPLE MAIL TRANSFER PROTOCOL
http://www.ietf.org/rfc/rfc821.txt
[URL]SMTP Service Extensions
http://www.ietf.org/rfc/rfc1869.txt
ソケットを使ってSMTPでメールを送信するサンプルは、次の「SMTP認
証でメールを送信するには?」で示しますので、そちらをご覧くださ
い。
○この記事の基になった掲示板のスレッド
[題名] SMTPでメール送信にて
[投稿者(敬称略)] きみ, りょう
[URL] http://dobon.net/vb/bbs/log3-5/2813.html
───────────────────────────────
●SMTP認証でメールを送信するには?
Socketを使ってSMTPでメールを送るには?
【質問】
SMTP認証(SMTP-AUTH)によりメールを送信したいのですが、どのよ
うな方法がありますか?
【回答】
上で紹介した方法と同様に、.NET Framework 1.1では、MailMessage
クラスのFieldsプロパティを使用することにより、System.Web.Mail.
SmtpMailクラスでもSMTP認証によるメールの送信ができます。この方
法は「The Code Project」で紹介されています。
[URL]The Code Project - SMTP Authentication using System.Web.
Mail (CDOSYS)
http://www.codeproject.com/dotnet/SystemWeb_Mail_SMTP_AUTH.asp
‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
System.Web.Mail.MailMessage mail = new System.Web.Mail.MailMessage();
//From
mail.From = "xxx@xxx.xxx";
//To
mail.To = "xxx@xxx.xxx";
//Subject
mail.Subject = "テスト";
//本文
mail.Body = "これはテストです。";
//smtpauthenticateを使う時は必ず2にする
mail.Fields[
"http://schemas.microsoft.com/cdo/configuration/sendusing"]
= 2;
//sendusingを2にした時は、必ずサーバーとポートを指定する
//SMTPサーバーを指定
mail.Fields[
"http://schemas.microsoft.com/cdo/configuration/smtsperver"]
= "xxx.xxx.xxx";
//ポート番号を指定する
mail.Fields[
"http://schemas.microsoft.com/cdo/configuration/smtpserverport"]
= 25;
//認証を使う
//1はbasic認証、2はNTLM認証
mail.Fields[
"http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"]
= 1;
//ユーザー名
mail.Fields[
"http://schemas.microsoft.com/cdo/configuration/sendusername"]
= "xxx";
//パスワード
mail.Fields[
"http://schemas.microsoft.com/cdo/configuration/sendpassword"]
= "xxx";
System.Web.Mail.SmtpMail.SmtpServer = "xxx.xxx.xxx";
//メールを送信
System.Web.Mail.SmtpMail.Send(mail);
‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
Dim mail As New System.Web.Mail.MailMessage
'From
mail.From = "xxx@xxx.xxx"
'To
mail.To = "xxx@xxx.xxx"
'Subject
mail.Subject = "テスト"
'本文
mail.Body = "これはテストです。"
'smtpauthenticateを使う時は必ず2にする
mail.Fields.Item( _
"http://schemas.microsoft.com/cdo/configuration/sendusing") _
= 2
'sendusingを2にした時は、必ずサーバーとポートを指定する
'SMTPサーバーを指定
mail.Fields.Item( _
"http://schemas.microsoft.com/cdo/configuration/smtsperver") _
= "xxx.xxx.xxx"
'ポート番号を指定する
mail.Fields.Item( _
"http://schemas.microsoft.com/cdo/configuration/smtpserverport") _
= 25
'認証を使う
'1はbasic認証、2はNTLM認証
mail.Fields.Item( _
"http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
'ユーザー名
mail.Fields.Item( _
"http://schemas.microsoft.com/cdo/configuration/sendusername") _
= "xxx"
'パスワード
mail.Fields.Item( _
"http://schemas.microsoft.com/cdo/configuration/sendpassword") _
= "xxx"
System.Web.Mail.SmtpMail.SmtpServer = "xxx.xxx.xxx"
'メールを送信
System.Web.Mail.SmtpMail.Send(mail)
‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
CDOを使えない環境では、やはりこの方法は無理です。前の「ポート
番号を指定してSMTPでメールを送るには?」で予告したように、ここ
ではソケットを使ってSMTPメール送信するサンプルを示します。しか
しこれはあくまでただの簡単なサンプルでしかありませんので、何も
理解せずに、このコードをそのまま利用することは絶対にしないでく
ださい。RFCを読み気がない、あるいは理解できないという方は、「
BASP21 DLL」や市販品をご利用ください。
なおこのクラスの使い方に関しては、エントリポイントのSmtpクラス
のMainメソッドを参考にしてください。
‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
using System;
using System.Net.Sockets;
using System.Text;
using System.Collections.Specialized;
namespace Dobon.Mail
{
///
/// 送信用のメールメッセージ
///
public class SmtpMailMessage
{
private string _from;
///
/// 送信者のメールアドレス
///
public string From
{
get
{
return _from;
}
set
{
_from = value;
}
}
private string _to;
///
/// 送信先のメールアドレス
///
public string To
{
get
{
return _to;
}
set
{
_to = value;
}
}
private string _subject;
///
/// メールの件名
///
public string Subject
{
get
{
return _subject;
}
set
{
_subject = value;
}
}
private string _body;
///
/// メールの本文
///
public string Body
{
get
{
return _body;
}
set
{
_body = value;
}
}
}
///
/// SMTPでメールを送信する
///
public class Smtp
{
///
/// エントリポイント
///
public static void Main()
{
SmtpMailMessage mail = new SmtpMailMessage();
//From
mail.From = "xxx@xxx.xxx";
//To
mail.To = "xxx@xxx.xxx";
//Subject
mail.Subject = "テスト";
//本文
mail.Body = "これはテストです。";
Smtp smtp = new Smtp();
//SMTPサーバー名
smtp.SmtpServer = "xxx.xxx.xxx";
//ポート番号
smtp.SmtpPort = 25;
//認証
smtp.AuthMethod = SmtpAuthMethod.Plain;
smtp.AuthUserName = "xxxxx";
smtp.AuthPassword = "xxxxx";
//送信する
smtp.Send(mail);
Console.ReadLine();
}
private string _smtpServer;
///
/// SMTPサーバー
///
public string SmtpServer
{
get
{
return _smtpServer;
}
set
{
_smtpServer = value;
}
}
private int _smtpPort = 25;
///
/// ポート番号
///
public int SmtpPort
{
get
{
return _smtpPort;
}
set
{
_smtpPort = value;
}
}
private string _authUserName;
///
/// 認証で用いるユーザー名
///
public string AuthUserName
{
get
{
return _authUserName;
}
set
{
_authUserName = value;
}
}
private string _authPassword;
///
/// 認証で用いるパスワード
///
public string AuthPassword
{
get
{
return _authPassword;
}
set
{
_authPassword = value;
}
}
///
/// SMTPの認証方法
///
public enum SmtpAuthMethod
{
None,
Plain,
Login
}
private SmtpAuthMethod _authMethod = SmtpAuthMethod.None;
///
/// 認証方法
///
public SmtpAuthMethod AuthMethod
{
get
{
return _authMethod;
}
set
{
_authMethod = value;
}
}
private NetworkStream _stream;
private string _recMsg;
private string boundary;
///
/// メールを送信する
///
/// 送信するメール
public void Send(SmtpMailMessage mail)
{
TcpClient soc = new TcpClient();
//接続
soc.Connect(SmtpServer, SmtpPort);
_stream = soc.GetStream();
try
{
ReceiveData();
if (!_recMsg.StartsWith("220"))
throw new ApplicationException("接続に失敗しました。");
SendData("EHLO\r\n");
ReceiveData();
if (!_recMsg.StartsWith("250"))
throw new ApplicationException(_recMsg);
//認証する
if (AuthMethod != SmtpAuthMethod.None)
Authenticate();
SendData("MAIL FROM:" + mail.From + "\r\n");
ReceiveData();
if (!_recMsg.StartsWith("250"))
throw new ApplicationException(_recMsg);
SendData("RCPT TO:" + mail.To + "\r\n");
ReceiveData();
if (!_recMsg.StartsWith("250"))
throw new ApplicationException(_recMsg);
SendData("DATA\r\n");
ReceiveData();
if (!_recMsg.StartsWith("354"))
throw new ApplicationException(_recMsg);
//送信データ
string data = "";
data += "From: " + mail.From + "\r\n";
data += "To: " + mail.To + "\r\n";
//件名をBase64でエンコード
data += "Subject: =?ISO-2022-JP?B?" +
GetBase64String(mail.Subject) + "?=" + "\r\n";
data += "MIME-Version: 1.0\r\n";
data += "Content-Transfer-Encoding: 7bit\r\n";
data += "Content-Type: text/plain; charset=ISO-2022-JP\r\n";
data += "\r\n" +
mail.Body.Replace("\r\n.\r\n", "\r\n..\r\n")
+ "\r\n";
data += ".\r\n";
SendData(data);
ReceiveData();
SendData("QUIT\r\n");
ReceiveData();
}
finally
{
//切断する
soc.Close();
}
}
//データを受信する
private void ReceiveData()
{
Encoding enc = Encoding.GetEncoding(50220);
byte[] data = new byte[1024];
int len;
string str = "";
System.IO.MemoryStream ms = new System.IO.MemoryStream();
//すべて受信する
do
{
//受信
len = _stream.Read(data, 0, data.Length);
ms.Write(data, 0, len);
//文字列に変換する
str = enc.GetString(ms.ToArray());
}
while (!str.EndsWith("\r\n") ||
System.Text.RegularExpressions.Regex.IsMatch(
str, @"(?:^|\n)\d+-[^\r\n]*\r\n$"));
ms.Close();
//表示
Console.Write("S: " + str);
_recMsg = str;
}
//データを送信する
private void SendData(string str)
{
Encoding enc = Encoding.GetEncoding(50220);
//byte型配列に変換
byte[] data = enc.GetBytes(str);
//送信
_stream.Write(data, 0, data.Length);
//表示
Console.Write("C: " + str);
}
//JISでエンコードし、Base64に変換
private string GetBase64String(string str)
{
Encoding enc = Encoding.GetEncoding(50220);
return Convert.ToBase64String(enc.GetBytes(str));
}
//認証を行う
private void Authenticate()
{
if (AuthMethod == SmtpAuthMethod.Plain)
{
//PLAIN
SendData("AUTH PLAIN\r\n");
ReceiveData();
if (!_recMsg.StartsWith("334"))
{
if (_recMsg.StartsWith("502"))
//認証の必要なし
return;
throw new ApplicationException(_recMsg);
}
string str = AuthUserName + '\0' + AuthUserName +
'\0' + AuthPassword;
SendData(GetBase64String(str) + "\r\n");
ReceiveData();
if (!_recMsg.StartsWith("235"))
throw new ApplicationException(_recMsg);
}
else if (AuthMethod == SmtpAuthMethod.Login)
{
//LOGIN
SendData("AUTH LOGIN\r\n");
ReceiveData();
if (!_recMsg.StartsWith("334"))
{
if (_recMsg.StartsWith("502"))
//認証の必要なし
return;
throw new ApplicationException(_recMsg);
}
SendData(GetBase64String(AuthUserName) + "\r\n");
ReceiveData();
if (!_recMsg.StartsWith("334"))
throw new ApplicationException(_recMsg);
SendData(GetBase64String(AuthPassword) + "\r\n");
ReceiveData();
if (!_recMsg.StartsWith("235"))
throw new ApplicationException(_recMsg);
}
}
}
}
‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
Imports System
Imports System.Net.Sockets
Imports System.Text
Imports System.Collections.Specialized
Namespace Dobon.Mail
'''
''' 送信用のメールメッセージ
'''
Public Class SmtpMailMessage
Private _from As String
'''
''' 送信者のメールアドレス
'''
Public Property From() As String
Get
Return _from
End Get
Set(ByVal Value As String)
_from = Value
End Set
End Property
Private _to As String
'''
''' 送信先のメールアドレス
'''
Public Property [To]() As String
Get
Return _to
End Get
Set(ByVal Value As String)
_to = Value
End Set
End Property
Private _subject As String
'''
''' メールの件名
'''
Public Property Subject() As String
Get
Return _subject
End Get
Set(ByVal Value As String)
_subject = Value
End Set
End Property
Private _body As String
'''
''' メールの本文
'''
Public Property Body() As String
Get
Return _body
End Get
Set(ByVal Value As String)
_body = Value
End Set
End Property
End Class
'''
''' SMTPでメールを送信する
'''
Public Class Smtp
'''
''' エントリポイント
'''
Public Shared Sub Main()
Dim mail As New SmtpMailMessage
'From
mail.From = "xxx@xxx.xxx"
'To
mail.To = "xxx@xxx.xxx"
'Subject
mail.Subject = "テスト"
'本文
mail.Body = "これはテストです。"
Dim smtp As New Smtp
'SMTPサーバー名
smtp.SmtpServer = "xxx.xxx.xxx"
'ポート番号
smtp.SmtpPort = 25
'認証
smtp.AuthMethod = SmtpAuthMethod.Plain
smtp.AuthUserName = "xxxxx"
smtp.AuthPassword = "xxxxx"
'送信する
smtp.Send(mail)
Console.ReadLine()
End Sub
Private _smtpServer As String
'''
''' SMTPサーバー
'''
Public Property SmtpServer() As String
Get
Return _smtpServer
End Get
Set(ByVal Value As String)
_smtpServer = Value
End Set
End Property
Private _smtpPort As Integer = 25
'''
''' ポート番号
'''
Public Property SmtpPort() As Integer
Get
Return _smtpPort
End Get
Set(ByVal Value As Integer)
_smtpPort = Value
End Set
End Property
Private _authUserName As String
'''
''' 認証で用いるユーザー名
'''
Public Property AuthUserName() As String
Get
Return _authUserName
End Get
Set(ByVal Value As String)
_authUserName = Value
End Set
End Property
Private _authPassword As String
'''
''' 認証で用いるパスワード
'''
Public Property AuthPassword() As String
Get
Return _authPassword
End Get
Set(ByVal Value As String)
_authPassword = Value
End Set
End Property
'''
''' SMTPの認証方法
'''
Public Enum SmtpAuthMethod
None
Plain
Login
End Enum
Private _authMethod As SmtpAuthMethod = SmtpAuthMethod.None
'''
''' 認証方法
'''
Public Property AuthMethod() As SmtpAuthMethod
Get
Return _authMethod
End Get
Set(ByVal Value As SmtpAuthMethod)
_authMethod = Value
End Set
End Property
Private _stream As NetworkStream
Private _recMsg As String
Private boundary As String
'''
''' メールを送信する
'''
''' 送信するメール
Public Sub Send(ByVal mail As SmtpMailMessage)
Dim soc As New TcpClient
'接続
soc.Connect(SmtpServer, SmtpPort)
_stream = soc.GetStream()
Try
ReceiveData()
If Not _recMsg.StartsWith("220") Then
Throw New ApplicationException("接続に失敗しました。")
End If
SendData("EHLO" + vbCrLf)
ReceiveData()
If Not _recMsg.StartsWith("250") Then
Throw New ApplicationException(_recMsg)
End If
'認証する
If AuthMethod <> SmtpAuthMethod.None Then
Authenticate()
End If
SendData(("MAIL FROM:" + mail.From + vbCrLf))
ReceiveData()
If Not _recMsg.StartsWith("250") Then
Throw New ApplicationException(_recMsg)
End If
SendData(("RCPT TO:" + mail.To + vbCrLf))
ReceiveData()
If Not _recMsg.StartsWith("250") Then
Throw New ApplicationException(_recMsg)
End If
SendData("DATA" + vbCrLf)
ReceiveData()
If Not _recMsg.StartsWith("354") Then
Throw New ApplicationException(_recMsg)
End If
'送信データ
Dim data As String = ""
data += "From: " + mail.From + vbCrLf
data += "To: " + mail.To + vbCrLf
'件名をBase64でエンコード
data += "Subject: =?ISO-2022-JP?B?" + _
GetBase64String(mail.Subject) + "?=" + vbCrLf
data += "MIME-Version: 1.0" + vbCrLf
data += "Content-Transfer-Encoding: 7bit" + vbCrLf
data += "Content-Type: text/plain; charset=ISO-2022-JP" _
+ vbCrLf
data += vbCrLf + mail.Body.Replace( _
vbCrLf + "." + vbCrLf, vbCrLf + ".." + vbCrLf) _
+ vbCrLf
data += "." + vbCrLf
SendData(data)
ReceiveData()
SendData("QUIT" + vbCrLf)
ReceiveData()
Finally
'切断する
soc.Close()
End Try
End Sub
'データを受信する
Private Sub ReceiveData()
Dim enc As Encoding = Encoding.GetEncoding(50220)
Dim data(1024) As Byte
Dim len As Integer
Dim str As String = ""
Dim ms As New System.IO.MemoryStream
'すべて受信する
Do
'受信
len = _stream.Read(data, 0, data.Length)
ms.Write(data, 0, len)
'文字列に変換する
str = enc.GetString(ms.ToArray())
Loop While Not str.EndsWith(vbCrLf) OrElse _
System.Text.RegularExpressions.Regex.IsMatch( _
str, "(?:^|\n)\d+-[^\r\n]*\r\n$")
ms.Close()
'表示
Console.Write(("S: " + str))
_recMsg = str
End Sub
'データを送信する
Private Sub SendData(ByVal str As String)
Dim enc As Encoding = Encoding.GetEncoding(50220)
'byte型配列に変換
Dim data As Byte() = enc.GetBytes(str)
'送信
_stream.Write(data, 0, data.Length)
'表示
Console.Write(("C: " + str))
End Sub
'JISでエンコードし、Base64に変換
Private Function GetBase64String(ByVal str As String) As String
Dim enc As Encoding = Encoding.GetEncoding(50220)
Return Convert.ToBase64String(enc.GetBytes(str))
End Function
'認証を行う
Private Sub Authenticate()
If AuthMethod = SmtpAuthMethod.Plain Then
'PLAIN
SendData("AUTH PLAIN" + vbCrLf)
ReceiveData()
If Not _recMsg.StartsWith("334") Then
If _recMsg.StartsWith("502") Then
'認証の必要なし
Return
End If
Throw New ApplicationException(_recMsg)
End If
Dim str As String = AuthUserName + _
ControlChars.NullChar + AuthUserName + _
ControlChars.NullChar + AuthPassword
SendData((GetBase64String(str) + vbCrLf))
ReceiveData()
If Not _recMsg.StartsWith("235") Then
Throw New ApplicationException(_recMsg)
End If
ElseIf AuthMethod = SmtpAuthMethod.Login Then
'LOGIN
SendData("AUTH LOGIN" + vbCrLf)
ReceiveData()
If Not _recMsg.StartsWith("334") Then
If _recMsg.StartsWith("502") Then
'認証の必要なし
Return
End If
Throw New ApplicationException(_recMsg)
End If
SendData((GetBase64String(AuthUserName) + vbCrLf))
ReceiveData()
If Not _recMsg.StartsWith("334") Then
Throw New ApplicationException(_recMsg)
End If
SendData((GetBase64String(AuthPassword) + vbCrLf))
ReceiveData()
If Not _recMsg.StartsWith("235") Then
Throw New ApplicationException(_recMsg)
End If
End If
End Sub
End Class
End Namespace
‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
○この記事の基になった掲示板のスレッド
[題名] SMTP-AUTHでのメール送信
[投稿者(敬称略)] smith, Moo, 中博俊, 管理人
[URL] http://dobon.net/cgi-bin/vbbbs/cbbs.cgi?mode=al2&namber=8968&no=0
(このURLは将来変更されます。)
===============================
■ここで示したコードの多くはまずC#で書き、それを「C# to VB.NET
Translator」でVB.NETのコードに変換し、修正を加えたものです。
[URL]C# to VB.NET Translator
http://authors.aspalliance.com/aldotnet/examples/translate.aspx
■このマガジンの購読、購読中止、バックナンバー、説明に関しては
次のページをご覧ください。
http://www.mag2.com/m/0000104516.htm
■発行人・編集人:どぼん!
(Microsoft MVP for Visual Basic, Oct 2004-Oct 2005)
http://dobon.net
dobon_info@yahoo.co.jp
■ご質問等はメールではなく、掲示板へお願いいたします。
http://dobon.net/vb/bbs.html
■上記メールアドレスへのメールは確実に読まれる保障はありません
(スパム、ウィルス対策です)。メールは下記URLのフォームメール
から送信してください。
http://dobon.net/mail.html
Copyright (c) 2003 - 2005 DOBON! All rights reserved.
===============================