- 追加された行はこの色です。
- 削除された行はこの色です。
*.NETプログラミング研究 第51号 [#lffd7c1e]
**.NET質問箱 [#tfbf2273]
「.NET質問箱」では、「どぼん!のプログラミング掲示板」に書き込まれた.NETプログラミングに関する投稿を基に、さらに考察を加え、Q&A形式にまとめて紹介します。
-[[どぼん!のプログラミング掲示板>http://dobon.net/vb/bbs.html]]
***ポート番号を指定してSMTPでメールを送るには? [#od89c161]
''【質問】''
System.Web.Mail.SmtpMailクラスでメールを送信する時、25以外のポート番号を指定することができないようです。25以外のポート番号を指定してメールを送信するには、どうしたらよいのでしょうか?
''【回答】''
.NET Framework 1.1では、MailMessageクラスにFieldsプロパティが加わり、これを使うことにより、CDOのフィールドにアクセスできるようになりました。これを使ってCDOのsmtpserverportフィールドを変更すれば、System.Web.Mail.SmtpMailクラスでもポート番号を指定してメールを送信することができます。
#code(csharp){{
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);
}}
#code(vbnet){{
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)
}}
参考:
-[[The Code Project - SMTP Authentication using System.Web.Mail (CDOSYS)>http://www.codeproject.com/dotnet/SystemWeb_Mail_SMTP_AUTH.asp]]
-[[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を使ってメールを送信するサンプルを紹介しましょう。遅延バインディングを行っているため、ちょっと複雑になっています。
#code(csharp){{
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[] {});
}}
#code(vbnet){{
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() {})
}}
CDOを使えない、あるいは使いたくないという場合は、自分でコードを書くか、誰かが作ったコンポーネントやクラスを使わせてもらうかということになるでしょう。例えば、Tatsuo Babaさんの「BASP21 DLL」を使わせていただくのも有効な方法の一つです。
-[[Baba Centerfolds>http://www.hi-ho.ne.jp/babaq/index.html]]
自分でコードを書くということになると、ソケットを使用することになります。この場合はもちろん、SMTPやMIMEに関する知識が必要です。SMTPについてRFCではRFC821で、さらにESMTPについてはRFC1869などで定義されています。
-[[SIMPLE MAIL TRANSFER PROTOCOL>http://www.ietf.org/rfc/rfc821.txt]]
-[[SMTP Service Extensions>http://www.ietf.org/rfc/rfc1869.txt]]
ソケットを使ってSMTPでメールを送信するサンプルは、次の「SMTP認証でメールを送信するには?」で示しますので、そちらをご覧ください。
○この記事の基になった掲示板のスレッド
-[[SMTPでメール送信にて | 投稿者(敬称略) きみ, りょう>http://dobon.net/vb/bbs/log3-5/2813.html]]
***SMTP認証でメールを送信するには? / Socketを使ってSMTPでメールを送るには? [#h3e946df]
''【質問】''
SMTP認証(SMTP-AUTH)によりメールを送信したいのですが、どのような方法がありますか?
''【回答】''
上で紹介した方法と同様に、.NET Framework 1.1では、MailMessageクラスのFieldsプロパティを使用することにより、System.Web.Mail.SmtpMailクラスでもSMTP認証によるメールの送信ができます。この方法は「The Code Project」で紹介されています。
-[[The Code Project - SMTP Authentication using System.Web.Mail (CDOSYS)>http://www.codeproject.com/dotnet/SystemWeb_Mail_SMTP_AUTH.asp]]
#code(csharp){{
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);
}}
#code(vbnet){{
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)
}}
CDOを使えない環境では、やはりこの方法は無理です。前の「ポート番号を指定してSMTPでメールを送るには?」で予告したように、ここではソケットを使ってSMTPメール送信するサンプルを示します。しかしこれはあくまでただの簡単なサンプルでしかありませんので、何も理解せずに、このコードをそのまま利用することは絶対にしないでください。RFCを読み気がない、あるいは理解できないという方は、「BASP21 DLL」や市販品をご利用ください。
なおこのクラスの使い方に関しては、エントリポイントのSmtpクラスのMainメソッドを参考にしてください。
#code(csharp){{
using System;
using System.Net.Sockets;
using System.Text;
using System.Collections.Specialized;
namespace Dobon.Mail
{
/// <summary>
/// 送信用のメールメッセージ
/// </summary>
public class SmtpMailMessage
{
private string _from;
/// <summary>
/// 送信者のメールアドレス
/// </summary>
public string From
{
get
{
return _from;
}
set
{
_from = value;
}
}
private string _to;
/// <summary>
/// 送信先のメールアドレス
/// </summary>
public string To
{
get
{
return _to;
}
set
{
_to = value;
}
}
private string _subject;
/// <summary>
/// メールの件名
/// </summary>
public string Subject
{
get
{
return _subject;
}
set
{
_subject = value;
}
}
private string _body;
/// <summary>
/// メールの本文
/// </summary>
public string Body
{
get
{
return _body;
}
set
{
_body = value;
}
}
}
/// <summary>
/// SMTPでメールを送信する
/// </summary>
public class Smtp
{
/// <summary>
/// エントリポイント
/// </summary>
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;
/// <summary>
/// SMTPサーバー
/// </summary>
public string SmtpServer
{
get
{
return _smtpServer;
}
set
{
_smtpServer = value;
}
}
private int _smtpPort = 25;
/// <summary>
/// ポート番号
/// </summary>
public int SmtpPort
{
get
{
return _smtpPort;
}
set
{
_smtpPort = value;
}
}
private string _authUserName;
/// <summary>
/// 認証で用いるユーザー名
/// </summary>
public string AuthUserName
{
get
{
return _authUserName;
}
set
{
_authUserName = value;
}
}
private string _authPassword;
/// <summary>
/// 認証で用いるパスワード
/// </summary>
public string AuthPassword
{
get
{
return _authPassword;
}
set
{
_authPassword = value;
}
}
/// <summary>
/// SMTPの認証方法
/// </summary>
public enum SmtpAuthMethod
{
None,
Plain,
Login
}
private SmtpAuthMethod _authMethod = SmtpAuthMethod.None;
/// <summary>
/// 認証方法
/// </summary>
public SmtpAuthMethod AuthMethod
{
get
{
return _authMethod;
}
set
{
_authMethod = value;
}
}
private NetworkStream _stream;
private string _recMsg;
private string boundary;
/// <summary>
/// メールを送信する
/// </summary>
/// <param name="mail">送信するメール</param>
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);
}
}
}
}
}}
#code(vbnet){{
Imports System
Imports System.Net.Sockets
Imports System.Text
Imports System.Collections.Specialized
Namespace Dobon.Mail
''' <summary>
''' 送信用のメールメッセージ
''' </summary>
Public Class SmtpMailMessage
Private _from As String
''' <summary>
''' 送信者のメールアドレス
''' </summary>
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
''' <summary>
''' 送信先のメールアドレス
''' </summary>
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
''' <summary>
''' メールの件名
''' </summary>
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
''' <summary>
''' メールの本文
''' </summary>
Public Property Body() As String
Get
Return _body
End Get
Set(ByVal Value As String)
_body = Value
End Set
End Property
End Class
''' <summary>
''' SMTPでメールを送信する
''' </summary>
Public Class Smtp
''' <summary>
''' エントリポイント
''' </summary>
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
''' <summary>
''' SMTPサーバー
''' </summary>
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
''' <summary>
''' ポート番号
''' </summary>
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
''' <summary>
''' 認証で用いるユーザー名
''' </summary>
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
''' <summary>
''' 認証で用いるパスワード
''' </summary>
Public Property AuthPassword() As String
Get
Return _authPassword
End Get
Set(ByVal Value As String)
_authPassword = Value
End Set
End Property
''' <summary>
''' SMTPの認証方法
''' </summary>
Public Enum SmtpAuthMethod
None
Plain
Login
End Enum
Private _authMethod As SmtpAuthMethod = SmtpAuthMethod.None
''' <summary>
''' 認証方法
''' </summary>
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
''' <summary>
''' メールを送信する
''' </summary>
''' <param name="mail">送信するメール</param>
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
}}
○この記事の基になった掲示板のスレッド
-[[SMTP-AUTHでのメール送信 | 投稿者(敬称略) smith, Moo, 中博俊, 管理人>http://dobon.net/cgi-bin/vbbbs/cbbs.cgi?mode=al2&namber=8968&no=0]]
//これより下は編集しないでください
#pageinfo(,2010-03-17 (水) 00:20:15,DOBON!,2010-03-17 (水) 00:20:15,DOBON!)