線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4836
推到 Plurk!
推到 Facebook!

以 NMSMTP 元件傳送郵件失敗 ?

尚未結案
yandav
一般會員


發表:16
回覆:20
積分:7
註冊:2002-10-05

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-10-30 12:38:16 IP:203.70.xxx.xxx 訂閱
各位前輩,大家好:
我的環境是 D5. 在程式中,若以 seednet 做 smtp server :
NMSMTP1.Host:='seed.net.tw';
則可以順利發送郵件.
但若以 pchome 做 smtp server :
NMSMTP1.Host:='smtp.pchome.com.tw';
則會出現下列之錯誤訊息 :
554 5.5.1 Error : no valid recipients

不知是哪裡出錯?
還請前輩們幫忙. 謝謝!!
danny
版主


發表:100
回覆:522
積分:595
註冊:2002-03-11

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-11-09 10:27:12 IP:203.79.xxx.xxx 訂閱
你先確定 smtp.pchome.com.tw 有開放給其他軟體使用 ? ex: Lookout Express
我記得 pchome 對外的 e-mail 很多都收不到也發不出去

===================引 用 yandav 文 章===================
各位前輩,大家好:
我的環境是 D5. 在程式中,若以 seednet 做 smtp server :
NMSMTP1.Host:='seed.net.tw';
則可以順利發送郵件.
但若以 pchome 做 smtp server :
NMSMTP1.Host:='smtp.pchome.com.tw';
則會出現下列之錯誤訊息 :
554 5.5.1 Error : no valid recipients

不知是哪裡出錯?
還請前輩們幫忙. 謝謝!!
------
將問題盡快結案也是一種禮貌!
cwc65536
初階會員


發表:47
回覆:121
積分:48
註冊:2004-10-14

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-11-09 12:10:06 IP:220.133.xxx.xxx 訂閱
你寄信的帳號是 pchome 嗎 ?
一般 Mail Server 為了怕被當成 垃圾信的跳板, 都會將 Open Relay 功能關閉
只有經過認證的帳號才能寄
HomeSound
中階會員


發表:44
回覆:178
積分:94
註冊:2002-08-31

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-11-12 03:45:48 IP:219.80.xxx.xxx 訂閱
用BCB開發有身份認證功能的Email程式  
2004-12-12
列印自: 香港IT網
地址: http://www.hkitn.com/article.php/2386
用BCB開發有身份認證功能的Email程式
摘 要 本文介紹了如何增強BCB中發送電子郵件的NMSMTP控制項的功能,實現具有身份認證功能的郵件發送程式。
關鍵字 ESMTP,MIME,身份認證
引言
為了更有效地抑制垃圾郵件的氾濫,目前多數網站的郵件收發系統都使用了ESMTP服務的身份認證功能。即用戶
發送郵件時,需要對用戶的身份進行驗證,如果帳號或密碼錯誤,郵件伺服器會拒絕發送郵件。
Borland C Builder 6中有豐富的控制項供開發者使用,其中當然也包括郵件發送控制項NMSMTP,這個控制項
使用方便,但是惟一的缺點是不支援郵件發送時的身份認證功能。筆者通過對郵件發送協議的分析,在使用控制
項的基礎上設計了具有身份認證功能的郵件發送程式。
ESMTP協議分析
為了實現身份認證功能,目前ESMTP協定中增加了一部分內容,這就是身份認證。下面我們看看這段認證過程,
以筆者在網易的郵箱為例(其中C表示用戶端,S表示郵件伺服器):
(1)C: AUTH LOGIN
(1)用戶端向伺服器發送認證指令。
(2)S: 334 dXNlcm5hbWU6
(2)伺服器返回Base64編碼串,334意味成功。編碼字串解碼後為"username:",說明要求用戶端發送用戶名。
(3)C: d3lxX2puX3NkX2Nu
(3)用戶端發送Base64編碼的用戶名串,此處為"wyq_jn_sd_cn"。
(4)S: 334 UGFzc3dvcmQ6
(4)伺服器返回Base64編碼串,334意味成功。編碼字串解碼後為"password:",說明要求用戶端發送用戶密碼。
(5)C: 密碼略去
(5)用戶端發送Base64編碼的口令串,此處略去。
(6)S: 235 Authentication successful
(6)伺服器返回普通字串,235意味成功,表示認證成功可以發送郵件了。

MIME Base64編碼解釋
一般的電腦編碼的一個位元組是8bit,0——FF就是256種不同的8bit組合。我們現在要介紹的這種Base64編碼
則是每個位元組6bit,共有26=64種組合。其中每種組合對應一個字元,這些字元是
“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 /。”這就意味著每3個普通編碼可以
轉換成4個Base64編碼,那麼如果需要轉換的普通編碼不是3的整數倍怎麼辦?Base64規定,位元數不足的
位元組後面補0,然後差幾個字元補幾個‘=’號。
設計思路
我們可以使用NMSMTP控制項與郵件伺服器連接。通過調用Connect方法,然後監聽OnConnect事件;
在OnConnect事件裏我們可以增加身份認證功能。這裏是主要利用了NMSMTP從Powersock中繼承的一些基本網路
通訊函數,包括Read,DataAvailable,SendBuffer等來實做身份認證過程。如果身份認證成功,就可以繼續
進行郵件發送;否則,提示錯誤資訊,斷開網路連接。
程式開始
使用BCB設計如圖1所示的表單。
郵件伺服器 Edit1 收件人E-Mail Edit2
發信的E-Mail Edit3 主旨
用戶名稱 Edit4 內容
使用身份驗證CheckBox1
密碼 Edit5

登入Button 發送Button

圖1 程式主介面
1、在登錄按鈕的OnClick事件中使用連接函數
void __fastcall TForm1::Logon1Click(TObject *Sender)
{ AddLog("正在登錄" Edit1->Text "......");
NMSMTP1->Host = Edit1->Text; //主機位址
NMSMTP1->Port = 25; //主機埠,內定為25
NMSMTP1->UserID = Edit4->Text; //用戶名
NMSMTP1->Connect(); //連接主機
}
2、處理OnConnect事件
void __fastcall TForm1::NMSMTP1Connect(TObject *Sender)
{ AddLog("連接伺服器成功。");
AnsiString Data="",rData="";
bool b_ok;
if(CheckBox1->Checked)
{ Data="AUTH LOGIN\r\n"; //登錄請求命令
NMSMTP1->SendBuffer(Data.c_str(),Data.Length()); //命令發出
rData = WaitForReply(5); //等待接收返回資料,5秒內必須返回
b_ok = false;
if(rData.Length()>=3)
{ //334意味著伺服器要求輸入用戶名
if(rData.TrimLeft().SubString(0,3)=="334")
{ AddLog("正在驗證身份......");
b_ok =true;
}
}
if(!b_ok)
{ AddLog("登錄失敗,正在退出......");
NMSMTP1->Disconnect();
return;
}
rData="";
Data=encode(Edit4->Text) "\r\n"; //用戶名轉換為Base64編碼。
NMSMTP1->SendBuffer(Data.c_str(),Data.Length()); //發送用戶名
rData = WaitForReply(5);
b_ok=false;
if(rData.Length()>=3)
{ // 334意味著伺服器要求輸入密碼
if(rData.TrimLeft().SubString(0,3)=="334")
{ AddLog("正在驗證密碼中......");
b_ok =true;
}
}
if(!b_ok)
{ AddLog("登錄失敗,正在退出......");
NMSMTP1->Disconnect();
return;
}
rData="";
Data=encode(Edit5->Text) "\r\n";//密碼轉換成Base64編碼。
NMSMTP1->SendBuffer(Data.c_str(),Data.Length()); //發送密碼
rData=WaitForReply(5);
b_ok = false;
if(rData.Length()>=3)
{ if(rData.TrimLeft().SubString(0,3)=="235")
{ AddLog("登錄成功......");
b_ok =true;
}
}
if(!b_ok)
{ AddLog("登錄失敗,正在退出......");
NMSMTP1->Disconnect();
return;
}
}
SendMail->Enabled=true; //允許發送郵件
disconnect->Enabled=true; //允許斷開連接
Logon1->Enabled=false; //不允許再次登錄
}
3、MIME Base64編碼轉換
AnsiString TForm1::encode(AnsiString s)
{ int m_len; //字串長度
int i; //迴圈變數
int m_tmp; //臨時變數
AnsiString m_64code; //儲存Base64編碼的字串
char* m_s; //臨時存儲參數字串
//Base64字元表
char m_64[]= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 /";
m_len = s.Length();//取得字串長度
m_s = s.c_str();
m_64code=""; //返回串置空
//處理3的倍數以內的字元
for(i=0;i { m_tmp=m_s[i]/4;
m_64code =m_64[m_tmp];
m_tmp=m_s[i]%4*16 m_s[i 1]/16;
m_64code =m_64[m_tmp];
m_tmp=m_s[i 1]*4 m_s[i 2]/64;
m_64code =m_64[m_tmp];
m_tmp=m_s[i 2]d;
m_64code =m_64[m_tmp];
}
//如果字串的長度被3除餘2 ,不足的位數補0,尾部補“=”
if(m_len%3==2)
{ m_tmp=m_s[m_len-2]/4;
m_64code =m_64[m_tmp];
m_tmp=m_s[m_len-2]%4*16 m_s[m_len-1]/16;
m_64code =m_64[m_tmp];
m_tmp=m_s[m_len-1]*4;
m_64code =m_64[m_tmp];
m_64code ='=';
}
//如果字串的長度被3除餘1 ,不足的位數補0,尾部補兩個“=”
if(m_len%3==1)
{ m_tmp=m_s[m_len-1]/4;
m_64code =m_64[m_tmp];
m_tmp=m_s[m_len-1]%4*16;
m_64code =m_64[m_tmp];
m_64code ="==";
}
return m_64code;
}
結束語
本程式在Windows 2000環境下使用Borland C Builder 6.0編寫及測試的,分別使用網易和新浪郵箱做實驗,
都可以順利完成身份認證以及郵件發送功能。

責任編輯: 風隨行

http://www.cyut.edu.tw/~rcchen/courses/opened.html
很多單元務必要看.
------
--==多看.多學.多聽==--
yandav
一般會員


發表:16
回覆:20
積分:7
註冊:2002-10-05

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-11-12 10:23:01 IP:203.70.xxx.xxx 訂閱
感謝各位前輩的回覆.
此帳號在 OutLook Express 中設定,收發信件都沒問題
看了前輩們的說明,可能真是身分驗證的問題
但 HomeSound 前輩的說明,對我來說,太過艱澀
且又完全不懂 BCB,可否以 Delphi 再詳加教導,謝謝!
以下為我的程式碼
try
NMSMTP1.Host:='smtp.pchome.com.tw';
NMSMTP1.UserID:=MyMailAccount; //MyMailAccount為pchome信箱帳號
NMSMTP1.Connect;
NMSmtp1.PostMessage.FromName:='郵件管理員';
NMSmtp1.PostMessage.FromAddress:=MyMailAddress; //MyMailAddress為pchome完整之mailaddress
NMSmtp1.PostMessage.ToAddress.Text:=CustomAddress; //CustomAddress為收件者之mailaddress
NMSmtp1.PostMessage.Subject:='通知單';
NMSmtp1.PostMessage.Attachments.Clear;
NMSmtp1.PostMessage.Attachments.Add(attchfile); //attchfile為附加檔案
NMSmtp1.PostMessage.Body.Text:=MailBody; //MailBody為信件內容字串
NMSmtp1.SendMail;
ShowMessage('郵件傳送成功!');
except
ShowMessage('郵件傳送失敗!');
end;
fivker
一般會員


發表:24
回覆:38
積分:12
註冊:2006-12-05

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-01-04 15:19:53 IP:220.128.xxx.xxx 訂閱
我之前發信也出現類似的問題:no valid recipient

可參考底下這篇
http://delphi.ktop.com.tw/board.php?cid=30&fid=67&tid=33791
系統時間:2024-11-22 21:53:31
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!