步驟:
1 客戶端程序發送郵件到SMTP服務器
2 SMTP服務器傳遞郵件到pop3接受服務器
3 接受郵件客戶端從pop3上接受
(MPTP簡單郵件傳輸協議,POP3郵局協議)
標準字段:
1 from:表述產生這個信件的人,一般含有一個信箱(From:XX@CC.com)
2 sender:用於指示信件發送者與信件建立者是否不一樣(From:XXX@CC.net and Sender:XXX@CC.net) 並不一 樣
3 Reply-To:用於控制信件要回復的目的地
4 To:信件的主要收信人
5 Cc:信件的輔收信人
6 Bcc:密件抄送的縮寫
7 Message-IDL用於一個信件的惟一標誌,有SMTP服務器生成
8 Date含有電子郵件的建立日期和時間
9 Received:爲信件的一個特定的郵件投遞服務器記錄
10重發字段(Resent-*)
11Subject用於描述信件的主題
12Comments用於吧一個註釋添加到信件中
13擴展字段..(X-Loop ,X-Mailer)
MIME對信頭字段的擴展
MIME 對RFC822的字段補充了一些信頭字段,這些字段一般是在發送電子郵件的軟件在建立電子郵件時產生的,接受電子郵件的軟件提取其中的字段獲得有用的信息
MIME補充的信頭字段:
MIME-Version字段用於標誌使用的MIME版本號,這是爲了未來增長版本號解決兼容的問題。該字段是MIME信件惟一必需要求出現的字段。
目前只有一個MIME版本在使用,通常加入一下字段:
MIME-Version: 1.0
Content-Type是MIME中的主要字段,描述特定MIME實體中包含的數據。
這個字段有3部分:前兩部分組成媒體類型和1個可選分號分開的參數列表。如:
Content-Type:text/plain;charset="us-ascii"
其中text是媒體類型主類別,plain指媒體類型的附加層次類別。charset="us-ascii"是可選的參數列表。又如: Content-Type:text/html;charset=gb2312
指定媒體的主類型是text,但文本內容是HTML格式文件。使用字符集是GB2312。
Content-Transfer-Encoding,許多數據格式能夠包含在信件中容許的字符範圍以外的字節值,並且含有超過容許長度的數據行。一些數據格式的定義甚至沒有行的概念。Content-Transfer-Encoding字段解決這些問題.
該字段有5個值:7bit,8bit,binary,base64和quoted-printable.每一個值都不區分大小寫。符合MIME規範的郵件處理程序必須能對這些編碼正確處理
(1)7bit特色:
編碼長度不超過998字節的數據,且該數據以Crlf結束的行組成 .爲缺省編碼,若是不提供Content-Transfer-Encoding字段,就認爲是7bit編碼
(2)8bit特色:
與7bit同樣但容許US-ASCII 0
(3)binary編碼用於任意二進制8位數據,對行長度和容許的字符沒有限制。在MIME信件實體裏包含這種數據是不合法的,它僅僅是告訴指定數據的數據類型,而數據不是給隨郵件做爲郵件內容發送的。
(4)base64特色:
把二進制數據編碼成適合經過internet傳送的格式,在處理二進制數據做爲郵件實體內容發送時,這種編碼方式應用的最爲普遍
在base64編碼過程當中要注意:
1:編碼後的文本每行的長度:郵件的文本行每行應該控制在76個字符之內,若是超過需插入Crlf(回車換行)。插入的Crlf不須要編碼
2填充字符
(1)quoted-printable編碼有文本組成的數據,在行超過80個字符的狀況下頗有用
(2)x-uuencode 經常使用在MIME實體中進行標誌
5 MIME 媒體類型
Connect-Type是用於在信頭中指定媒體類型的字段,是MIME對RFC822擴展的主要信頭字段
Connect-Type: 媒體類型主類別/媒體類型的附加層次類別+有可選分號分開的參數列表。
一共有8個頂層的媒體類型:Text,Image,Audio,Video,Application,Message和Multipart.這些主要類型爲他們各自的數據提供了一個結構
(1)Text
Text類型用於指示基於文本的內容。這裏類別中任何子類型都不須要程序格式化數據而進行約定。參數有charset,用於指定Text所使用的字符集,缺省時爲US-ASCII.如:
Content-Type:text/plain;charset=us-ascii與Content-Type:text/plain是同樣的
Text的附加層次媒體類型還有:Plain, Enrich,Html等
1 TEXT:
text/plain 媒體類型標識有普通可打印字符組成,能夠是US-ASCII,也能夠是漢字,這些數據沒有通過格式化,直接瀏覽閱讀便可.
text/enrich 爲建立有對齊,顏色和字體變化功能的文本提供了一個簡單的標記語言。
text/Html
2 Image,Audio和Video
這幾個媒體的主要類別是至關直觀的,數據一般是二進制的,採用base64編碼
Content-Type:Image/jpeg
Content-Transfer-Encoding:base64
3 Application: 該媒體類別含有與特定應用文件格式有關的任何媒體類型。
幾種附加層次類別:
octet-stream ,Content-Type:Application/actet-stream
Application/actet-stream指示一個實體中含有任意數據,當內容未知或者對數據沒有定義媒體類型時,一般使用它
Postscript ,Content-Type:Application/Postscript
Application/Postscript媒體類型用於標識一個實體的內容是Postscript代碼。由於 Application/Postscript實體含有可執行代碼,他的內容必須毫無損失的到達目的地,也許是這個緣由,一般使用quoted- printable編碼,是他不至於由於長度限制或在經過Internet網關時被破壞
Message 這個媒體類型的主類別指定信體組成的實體
RFC822,Content-Type:message/RFC822
message/RFC822類型提供在一個信件中打包另一個信件的簡單方法。全部符合MIME的郵件處理程序都必須支持這種類型的分析
Partial,Content-Type:message/Partial
message/Partial媒體類型指定了一種方法,該方法把大的實體分紅多個部件,每一個部件能夠分開傳輸在接受端組裝,在發送和傳輸郵件的服務器之間有信件尺寸限制的狀況下,這種方法能夠傳送比較大的信件
External-body,content-type:message/External-body
message/External-body表示實體含有的數據並不在信件內容裏,而僅僅是描述了一種從外部取出數據的方式。
Multipart,Content-Type:mulipart/mixed
Multipart媒體類型的主類別表示多個實體打包到單個實體,多部件實體由一個可選的前導,一個或多個信件體部件(每一個前面有一個邊界行)和一個可選 的結尾部件組成。邊界行由兩個橫線後跟一個邊界字符串組成。這個邊界字符串由Content-Type字段中的參數boundary的值指定html
SMTP會話:
特色:
1 全過程發送文本完成,交互式請求應答模式
2 命令是文本形式的命令
3 服務器總返回必定的相應碼,表示客戶端的請求是否被正確的回答
4 會話過程有必定的順序
補充:
1 Email通訊是基於TCP/IP協議,要首先用WinSock創建和SMTP服務器的鏈接
2 鏈接成功後,要進行會話,SMTP有其認識的一整套命令,固然是事先約定好的,SMTP協議的很重要的一 部分就是會話的標準命令
3 不過駭心命令很少,甚至幾個就能完成會話服務器
一個簡單的會話 例子:
1:AfxSocketInit(NULL)
2:m_Socket.Create()
3:m_Socket.Connect(LPCSTR(temp),25)
4:virtual void OnReceive(int nErrorCode);等待服務器迴應接受m_Socket.Receive(sBuffer,sizeof (sBuffer));
5:發送m_Socket.Send("HELO smtp.sohu.com\r\n" ,len ) 返回4
6:發送m_Socket.Send("MAIL FROM: mmnihao_@sohu.com\r\n" ,len ) 返回4
7:發送m_Socket.Send("RCPT TO: mmnihao_@sohu.com\r\n" ,len ) 返回4
8:發送m_Socket.Send("DATA\r\n" ,len ) 返回4
9:發送m_Socket.Send("text\r\n\r\n.\r\n" ,len ) 返回4 (注意".")
9:發送m_Socket.Send("QUIT\r\n" ,len ) 返回4
10 結束併發
程序:
1定義一個CESocket類 繼承於CSocket負責相應接受數據消息,CESocket初始化Init
m_iCount 是一個命令發送的序號
//初始話
void CESocket::Init(CEmailSendDlg *dlg)
{
m_dlg=dlg;
m_iCount=0;
}
CESocket接受數據相應函數OnReceive,調用主對話框的接受消息處理函數,同時增長m_iCount
//接受數據響應函數,調用主對話框的接受消息處理函數,同時增長m_iCount
void CESocket::OnReceive(int nErrorCode)
{dom
m_dlg->ReceiveMessage(m_iCount);
m_iCount++;
CSocket::OnReceive(nErrorCode);
}ide
2:對話框的消息處理函數:
void CEmailSendDlg::OnSend()
{函數
GetDlgItemText(IDC_SMTP_ADDRESS, m_sSendString[0]);
GetDlgItemText(IDC_FROM_ADDRESS, m_sSendString[1]);
GetDlgItemText(IDC_TO_ADDRESS, m_sSendString[2]);oop
m_sSendString[0].TrimLeft(" ");
m_sSendString[0].TrimRight(" ");
m_sSendString[1].TrimLeft(" ");
m_sSendString[1].TrimRight(" ");
m_sSendString[2].TrimLeft(" ");
m_sSendString[2].TrimRight(" ");
if(m_sSendString[0].IsEmpty())
{
AfxMessageBox("請輸入SMTP服務器地址(IP)");
return;
}
if(m_sSendString[1].IsEmpty())
{
AfxMessageBox("請輸入你的EMail地址");
return;
}
if(m_sSendString[2].IsEmpty())
{
AfxMessageBox("請輸入收件人的EMail地址");
return;
}post
m_sSendString[0]="HELO "+m_sSendString[0]+"\r\n";
m_sSendString[1]="MAIL FROM: "+m_sSendString[1]+"\r\n";
m_sSendString[2]="RCPT TO: "+m_sSendString[2]+"\r\n";測試
m_sSendString[3]="DATA\r\n";
GetDlgItemText(IDC_EMAIL_CONTENT,m_sSendString[4]);
m_sSendString[4]=m_sSendString[4]+"\r\n\r\n.\r\n";
m_sSendString[5]="QUIT\r\n";字體
CString temp;
GetDlgItemText(IDC_SMTP_ADDRESS,temp);
if(m_Socket.Connect(LPCSTR(temp),25)==FALSE)
{
}
m_sReceivedData="";
}
當客戶端鏈接大SMTP服務器後,smtp會發送一段歡迎碼而後客戶端和服務器就能夠按照SMTP命令進行會話
直到信件發送結束
void CEmailSendDlg::ReceiveMessage(int count)
{
if(count>=6)
{
AfxMessageBox("Unknown Received Data");
m_Socket.Close();
return;
}
char sBuffer[255];
int len=m_Socket.Receive(sBuffer,sizeof(sBuffer));
sBuffer[len]=NULL;
m_sReceivedData=m_sReceivedData+sBuffer;
m_sReceivedData=m_sReceivedData+m_sSendString[count];
m_Socket.Send(m_sSendString[count],m_sSendString[count].GetLength());
}
//----------------------------------------------
如何獲取從發信服務器到網易MX服務器的SMTP會話樣例?字體: 小 中 大
利用telnet手工模擬一次smtp會話過程,能提供許多有用的信息,從而幫助咱們迅速定位您的問題。下面這個手工smtp會話測試過程能夠在多個操做系統下運行,包括Windows、Unix、和Linux。
本幫助講述了若是利用telnet來模擬一次完整的發信。請將您的整個會話過程複製下來,併發送給咱們。
2nn開頭的返回碼,表示會話是正常的。而5nn或者4nn開頭的返回碼則表示有錯誤發生。
注意:本測試過程必須在發信服務器上進行。
下面是具體步驟:
一、打開一個命令窗口,鍵入:
telnet mx.mail.126.split.netease.com 25
這條命令將創建一個到咱們126郵件服務器的鏈接。
二、 鍵入:
HELO yourdomain.com
這裏的yourdomain.com指您的域名。
三、 鍵入:
MAIL FROM:< you@yourdomain.com >(無需空格)
這裏的you@yourdomain.com指您們域的一個郵箱名。
注意:郵箱名須要用<>括起來。
4: 鍵入:
RCPT TO:< postmaster >(無需空格)
這將發信到咱們的postmaster郵箱。
注意:郵箱名須要用<>括起來。
5: 鍵入:
DATA
6: 輸入郵件的信頭和正文。
FROM:< you@yourdomain.com>(無需空格)
TO:< postmaster>(無需空格)
SUBJECT: yourdomain.com to netease
Hi! It's from yourdomain.com. Just a test. Bye. 7: 新起一個空行,鍵入: . 而後按回車,這將結束整封信,併發送給服務器