首先聲明:本文的內容及所涉及的技術,僅做學習和技術研究,並不涉及任何對相關公司軟件版權的有意侵犯。
放長假以來,天天在琢磨郵件的事,不過通過這幾天也還是認真的學習和了解了一下SMTP協議和指令,對郵件發送的各個方面也有了一些了解,特別是自己編寫的那個郵件發送平台小軟件為了做的更好,不得不一次次深入的學習,自己的能力也得到了提高。
在郵件發送小程序的編寫過程中,我做了幾次測試,發現郵件的發送速度都很慢,平均下來要15秒到16秒才能發出一封,這樣的話,如果我某個時段有100封郵件需要發送,那差不多要半個多小時,用手機發短信都用不了那麼長時間呀。一開始我以為是自己的代碼有問題,仔細檢查後沒有發現問題。下在糾結的時候,一次偶然的測試時,我沒有使用公司的SMTP服務器,而是使用了新浪的smtp.sina.com服務器,這時發現郵件發送的速度約為1至2秒一封,問題找到了,原來是出在公司的郵件服務器上。
公司的郵件服務器使用的是Lotus Notes 8.0,一台小型機,四千左右用戶,從理論上來說,不應該這麼慢。與郵件服務器管理員聯系,請他在後台監測一下發送的過程,他監測後告訴我,每發送一封郵件,都要連接一次服務器,而我們的服務器前段時間剛做了一次安全基線,加上了一個參數,“用於驗證的 SMTP 會話發送的郵件是否來自通過驗證的用戶的 Internet 地址,此設置的目的是確認用戶沒有嘗試偽造“收件人”域”。這有可能是造成每次連接服務器驗證時間過長的情況。相關信息如下:
[454808:00136-03743] 2010-10-08 13:32:13 SMTP Server: localhost (10.169.**.**) connected
[454808:00136-03743] 2010-10-08 13:32:13 SMTP Server: Authentication succeeded for user ******* ; connecting host 10.169.**.**
[454808:00136-02218] 2010-10-08 13:32:13 SMTP Server: Message 001E6A8C (MessageID: ) received
[454808:00136-03743] 2010-10-08 13:32:13 SMTP Server: localhost (10.169.**.**) disconnected. 1 message[s] received
[364650:00020-04113] 2010-10-08 13:32:13 Router: Message 001E6A8C delivered to *******
[454808:00136-02218] 2010-10-08 13:32:30 SMTP Server: localhost (10.169.**.**) connected
[454808:00136-02218] 2010-10-08 13:32:30 SMTP Server: Authentication succeeded for user ******* ; connecting host 10.169.**.**
[454808:00136-03743] 2010-10-08 13:32:30 SMTP Server: Message 001E710C (MessageID: ) received
[454808:00136-02218] 2010-10-08 13:32:30 SMTP Server: localhost (10.169.**.**) disconnected. 1 message[s] received
[364650:00016-03085] 2010-10-08 13:32:30 Router: Message 001E710C delivered to *******
如果問題的確是出在每次連接驗證的時候時間過長的話,如果是發送多封郵件,是否可以驗證一次後連續發送,最後再關閉呢?認真的查閱了Jmail.Net的各個參數,發現Jmail.Net並沒有提供這方面的功能,它只能每次發送一封郵件時連接一次服務器,它自身的群組郵件功能也不適用於我想達到的每封郵件內容不相同的目的,在網上搜索了一些相當內容也沒有合適的,最後決定自己動手改造Jmail.Net。
下載到一個Jmail.Net的反編譯源碼(需要的網友請自行搜索下載,這裡就不給出下載地址了),裝入VS2005,開始閱讀代碼。
從編寫代碼時的自動提示就可以看出,發送的代碼由Dimac.Jmail.Smtp.Send()來實現,直接查看Dimac.JMail.Smtp項目下的Smtp.cs代碼。定位到最主要的功能實現代碼上:
01
public
void
Send(Message message)
02
{
03
if
(message ==
null
)
04
{
05
throw
new
ArgumentNullException(
"message"
,
"Message cannot be null."
);
06
}
07
using
(SmtpClient client =
new
SmtpClient(
this
.m_logStream))
08
{
09
client.Connect(
this
.m_hostName,
this
.m_port);
10
client.Helo(
this
.m_domain);
11
client.Auth(
this
.m_authentication, (
this
.m_userName ==
null
) ?
string
.Empty :
this
.m_userName, (
this
.m_password ==