青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 126,  comments - 73,  trackbacks - 0
要:本文介紹了一種采用SMTP協(xié)議規(guī)范并通過直接使用SMTP協(xié)議命令而在程序中實現(xiàn)電子郵件傳送的方法。并在VC++開發(fā)環(huán)境下給出了部分關鍵的實現(xiàn)代碼。

  前言

  電子郵件服務作為Internet上應用最多和最廣的服務項目得到了非常廣泛的應用,在網(wǎng)絡應用中也起到非常重要的作用。如同其他的網(wǎng)絡服務,電子郵件系統(tǒng)也有其使用的傳輸協(xié)議,包括SMTP(Simple Mail Transfer Protocol,簡單郵件傳輸協(xié)議)、POP(Post Office Protocol,郵局協(xié)議)和IMAP(Internet Message Access Protocal,消息訪問協(xié)議)等,這些協(xié)議應用于電子郵件的發(fā)送和接收。一些郵件處理軟件如OutLook Express和FoxMail等就是按照SMTP和POP3 協(xié)議結(jié)合Windows Sockets套接字進行設計來收發(fā)郵件的。本文以SMTP協(xié)議為研究對象,在Visual C++ 6.0編程環(huán)境下按照SMTP協(xié)議通過套接字發(fā)送SMTP命令,接收并處理郵件服務器的反饋信息,從而實現(xiàn)對電子郵件的發(fā)送。

  SMTP協(xié)議的通訊模型和會話流程

  SMTP協(xié)議通訊模型

  SMTP協(xié)議是TCP/IP協(xié)議族中的一員,主要對如何將電子郵件從發(fā)送方地址傳送到接收方地址,也即是對傳輸?shù)囊?guī)則做了規(guī)定。SMTP協(xié)議的通信模型并不復雜,主要工作集中在發(fā)送SMTP和接收SMTP上:首先針對用戶發(fā)出的郵件請求,由發(fā)送SMTP建立一條連接到接收SMTP的雙工通訊鏈路,這里的接收SMTP是相對于發(fā)送SMTP而言的,實際上它既可以是最終的接收者也可以是中間傳送者。發(fā)送SMTP負責向接收SMTP發(fā)送SMTP命令,而接收SMTP則負責接收并反饋應答??纱笾掠孟旅娴耐ㄓ嵞P褪疽鈭D來表示:


  SMTP協(xié)議的命令和應答

  從前面的通訊模型可以看出SMTP協(xié)議在發(fā)送SMTP和接收SMTP之間的會話是靠發(fā)送SMTP的 SMTP命令和接收SMTP反饋的應答來完成的。在通訊鏈路建立后,發(fā)送SMTP發(fā)送MAIL命令指令郵件發(fā)送者,若接收SMTP此時可以接收郵件則作出OK的應答,然后發(fā)送SMTP繼續(xù)發(fā)出RCPT命令以確認郵件是否收到,如果接收到就作出OK的應答,否則就發(fā)出拒絕接收應答,但這并不會對整個郵件操作造成影響。雙方如此反復多次,直至郵件處理完畢。SMTP協(xié)議共包含10個SMTP命令,列表如下:

SMTP命令命令說明
HELLO <domain> <CRLF>識別發(fā)送方到接收SMTP的一個HELLO命令
MAIL FROM:<reverse-path><CRLF> <reverse-path>為發(fā)送者地址。此命令告訴接收方一個新郵件發(fā)送的開始,并對所有的狀態(tài)和緩沖區(qū)進行初始化。此命令開始一個郵件傳輸處理,最終完成將郵件數(shù)據(jù)傳送到一個或多個郵箱中。
RCPT TO:<forward-path><CRLF> <forward-path>標識各個郵件接收者的地址
DATA <CRLF>
接收SMTP將把其后的行為看作郵件數(shù)據(jù)去處理,以<CRLF>.<CRLF>標識數(shù)據(jù)的結(jié)尾。
REST <CRLF>退出/復位當前的郵件傳輸
NOOP <CRLF>要求接收SMTP僅做OK應答。(用于測試)
QUIT <CRLF>要求接收SMTP返回一個OK應答并關閉傳輸。
VRFY <string> <CRLF> 驗證指定的郵箱是否存在,由于安全因素,服務器多禁止此命令。
EXPN <string> <CRLF> 驗證給定的郵箱列表是否存在,擴充郵箱列表,也常禁止使用。
HELP <CRLF>查詢服務器支持什么命令

注:<CRLF>為回車、換行,ASCII碼分別為13、10(十進制)。

  SMTP協(xié)議的每一個命令都會返回一個應答碼,應答碼的每一個數(shù)字都是有特定含義的,如第一位數(shù)字為2時表示命令成功;為5表失??;3表沒有完成。一些較復雜的郵件程序利用該特點,首先檢查應答碼的首數(shù)字,并根據(jù)其值來決定下一步的動作。下面將SMTP的應答碼列表如下:

應答碼說明
501 參數(shù)格式錯誤
502 命令不可實現(xiàn)
503 錯誤的命令序列
504 命令參數(shù)不可實現(xiàn)
211 系統(tǒng)狀態(tài)或系統(tǒng)幫助響應
214 幫助信息
220<domain>服務就緒
221 <domain>服務關閉
421 <domain>服務未就緒,關閉傳輸信道
250要求的郵件操作完成
251 用戶非本地,將轉(zhuǎn)發(fā)向<forward-path>
450 要求的郵件操作未完成,郵箱不可用
550 要求的郵件操作未完成,郵箱不可用
451 放棄要求的操作;處理過程中出錯
551 用戶非本地,請嘗試<forward-path>
452 系統(tǒng)存儲不足,要求的操作未執(zhí)行
552 過量的存儲分配,要求的操作未執(zhí)行
553 郵箱名不可用,要求的操作未執(zhí)行
354 開始郵件輸入,以"."結(jié)束
554 操作失敗
  在應用程序中使用SMTP協(xié)議

  SMTP協(xié)議的會話流程

  在進行程序設計之前有必要弄清SMTP協(xié)議的會話流程,其實前面介紹的內(nèi)容已經(jīng)可以大致勾勒出用SMTP發(fā)送郵件的框架了,對于一次普通的郵件發(fā)送,其過程大致為:先建立TCP連接,隨后客戶端發(fā)出HELLO命令以標識發(fā)件人自己的身份,并繼續(xù)由客戶端發(fā)送MAIL命令,如服務器應答為"OK",可繼續(xù)發(fā)送RCPT命令來標識電子郵件的收件人,在這里可以有多個RCPT行,而服務器端則表示是否愿意為收件人接受該郵件。在雙方協(xié)商結(jié)束后,用命令DATA將郵件發(fā)送出去,其中對表示結(jié)束的"."也一并發(fā)送出去。隨后結(jié)束本次發(fā)送過程,以QUIT命令退出。下面通過一個實例,從langrui@sohu.com發(fā)送郵件到renping@sina.com來更詳細直觀地描述此會話流程:

R:220 sina.com Simple Mail Transfer Service Ready
S:HELLO sohu.com
R:250 sina.com
S:MAIL FROM:<langrui@sohu.com>
R:250 OK
S:RCPT TO:<renping@sina.com>
R:250 OK
S:DATA
R:354 Start mail input;end with "<CRLF>.<CRLF>"
S:……
R:250 OK
S:QUIT
R:221 sina.com Service closing transmission channel

  郵件的格式化

  由于電子郵件結(jié)構(gòu)上的特殊性,在傳輸時是不能當作簡單的文本來直接處理的,而必須按照一定的格式對郵件頭和郵件體進行格式化處理之后才可以被發(fā)送。需要進行格式化的部分主要有:發(fā)件人地址、收件人地址、主題和發(fā)送日期等。在RFC文檔的RFC 822里對郵件的格式化有詳盡的說明,有關詳情請參閱該文檔。下面通過VC++6.0按照RFC 822文檔規(guī)定將格式化郵件的部分編寫如下(部分代碼):

//郵件頭準備
strTemp = _T( "From: " ) + m_strFrom; file://發(fā)件人地址
add_header_line( (LPCTSTR)strTemp );
strTemp = _T( "To: " ) + m_strTo; file://收件人地址
add_header_line( (LPCTSTR)strTemp );
m_tDateTime = m_tDateTime.GetCurrentTime();//發(fā)送時間
strTemp = _T( "Data: " );
strTemp += m_tDateTime.Format( "%a, %d %b %y %H:%M:%S %Z" );
add_header_line( (LPCTSTR)strTemp );
strTemp = _T( "Subject: " ) + m_strSubject; file://主題
add_header_line( (LPCTSTR)strTemp );
file://郵件頭結(jié)束
m_strHeader += _T( "\r\n" );
file://郵件體準備
if( m_strBody.Right( 2 ) != _T( "\r\n" ) ) file://確認最后以回車換行結(jié)束
m_strBody += _T( "\r\n" );

  其中add_header_line(LPCTSTR szHeaderLine)函數(shù)用于把szHeaderLine指向的字串追加到m_strHeader后面。其中,格式化后的郵件頭保存在m_strHeader里,格式化后的郵件體保存在m_strBody中。

  由Socket套接字為SMTP提供網(wǎng)絡通訊基礎

  許多網(wǎng)絡程序都是采用Socket套接字實現(xiàn)的,對于一些標準的網(wǎng)絡協(xié)議如HTTP、FTP和SMTP等協(xié)議的編程也是基于套接字程序的,只是端口號不再是隨意設定而要由協(xié)議來指定,比如HTTP端口在80、FTP是21,而SMTP則是25。Socket只是提供在指定的端口上同指定的服務器從事網(wǎng)絡上的通訊能力,至于客戶和服務器之間是如何通訊的則由網(wǎng)絡協(xié)議來規(guī)定,這對于套接字是完全透明的。因此可以使用Socket套接字為程序提供網(wǎng)絡通訊的能力,而對于網(wǎng)絡通訊連路建立好之后采取什么樣的通訊應答則要按SMTP協(xié)議的規(guī)定去執(zhí)行了。Socket套接字網(wǎng)絡編程方面的文章資料非常豐富,限于本文篇幅,在此不再贅述,有關詳情請參閱相關文檔。為簡便起見,沒有采用編寫較復雜的Windows Sockets API進行編程,而是使用經(jīng)過較好封裝的MFC 的CSocket類。在正式使用套接字之前,也要先用AfxSocketInit()函數(shù)對套接字進行初始化,然后用Create()創(chuàng)建套接字對象,并由該套接字通過Connect()建立同郵件服務器的連接。如果一切正常,再后續(xù)的工作中就是遵循SMTP協(xié)議的約定來使用Send()、Receive()函數(shù)來發(fā)送SMTP命令和接收郵件服務器發(fā)來的應答碼以完成對郵件的傳送。

  SMTP會話應答的實現(xiàn)

  在同郵件服務器建立好鏈路連接后就可以按前面介紹過的會話流程進行程序設計了,對于SMTP命令的發(fā)送,可按命令格式將其組幀完畢后用CSocket類的Send()函數(shù)將其發(fā)送到服務器,并通過CSocket類的Receive()函數(shù)接收從郵件服務器發(fā)來的應答碼,并根據(jù)SMTP協(xié)議的應答碼表對其做出響應的處理。下面是用于接收應答碼的函數(shù)get_response()的部分實現(xiàn)代碼:

BOOL CSMTP::get_response( UINT response_expected )//輸入?yún)?shù)為希望的應答碼
{
……
// m_wsSMTPServer為CSocket的類對象,調(diào)用Receive()將應答碼接收到緩存
// response_buf中
m_wsSMTPServer.Receive( response_buf, RESPONSE_BUFFER_SIZE )
sResponse = response_buf;
sscanf( (LPCTSTR)sResponse.Left( 3 ), _T( "%d" ), &response );
pResp = &response_table[ response_expected ];
file://檢驗收到的應答碼是否是所希望得到的
if( response != pResp->nResponse )
{
……//不相等的話進行錯誤處理
return FALSE;
}
return TRUE;
}

  會話的各個部分比較類似,都是命令--應答方式,而且均成對出現(xiàn),下面是本文的重點也是實現(xiàn)的關鍵部分--在程序控制下完成對SMTP命令的格式化以及對命令的發(fā)送和對郵件服務器應答碼的檢驗處理:

//格式化并發(fā)送HELLO命令,并接收、驗證服務器應答碼
gethostname( local_host, 80 );
sHello.Format( _T( "HELO %s\r\n" ), local_host );
m_wsSMTPServer.Send( (LPCTSTR)sHello, sHello.GetLength() );
if( !get_response( GENERIC_SUCCESS ) ) file://檢驗應答碼是否為250
{
……
return FALSE;
}
file://格式化并發(fā)送MAIL命令,并接收、驗證服務器應答碼
sFrom.Format( _T( "MAIL From: <%s>\r\n" ), (LPCTSTR)msg->m_strFrom );
m_wsSMTPServer.Send( (LPCTSTR)sFrom, sFrom.GetLength() );
if( !get_response( GENERIC_SUCCESS ) ) file://檢驗應答碼是否為250
return FALSE;
file://格式化并發(fā)送RCPT命令,并接收、驗證服務器應答碼
sEmail=(LPCTSTR)msg->m_strTo;
sTo.Format( _T( "RCPT TO: <%s>\r\n" ), (LPCTSTR)sEmail );
m_wsSMTPServer.Send( (LPCTSTR)sTo, sTo.GetLength() );
if(!get_response( GENERIC_SUCCESS )) file://檢驗應答碼是否為250
return FALSE;
file://格式化并發(fā)送DATA命令,并接收、驗證服務器應答碼
sTemp = _T( "DATA\r\n" );
m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() );
if( !get_response( DATA_SUCCESS ) ) file://檢驗應答碼是否為354
return FALSE;
file://發(fā)送根據(jù)RFC 822文檔規(guī)定格式化過的郵件頭
m_wsSMTPServer.Send( (LPCTSTR)msg->m_strHeader, msg->m_strHeader.GetLength() );
……
file://發(fā)送根據(jù)RFC 822文檔規(guī)定格式化過的郵件體
sTemp = msg->m_strBody;
if( sTemp.Left( 3 ) == _T( ".\r\n" ) )
sTemp = _T( "." ) + sTemp;
while( (nPos = sTemp.Find( szBad )) > -1 )
{
sCooked = sTemp.Mid( nStart, nPos );
sCooked += szGood;
sTemp = sCooked + sTemp.Right( sTemp.GetLength() - (nPos + nBadLength) );
}
m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() );
file://發(fā)送內(nèi)容數(shù)據(jù)結(jié)束標志"<CRLF>.<CRLF>",并檢驗返回應答碼
sTemp = _T( "\r\n.\r\n" );
m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() );
if( !get_response( GENERIC_SUCCESS ) )// 檢驗應答碼是否為250
return FALSE;

  到此為止,已基本在程序中體現(xiàn)出了SMTP協(xié)議的會話流程,能在Socket套接字所提供的網(wǎng)絡通訊能力基礎之上實現(xiàn)以SMTP命令和SMTP應答碼為基本會話內(nèi)容的通訊交互過程,從而最終實現(xiàn)SMTP協(xié)議對電子郵件的發(fā)送。

  結(jié)論

  電子郵件類軟件作為Internet上的應用軟件,其設計開發(fā)必須符合Internet上成熟的技術(shù)規(guī)范(如RFC文檔系列規(guī)范)和相關協(xié)議(如POP、SMTP、IMAP以及LDAP等)。只有在遵循了上述規(guī)范和協(xié)議的基礎上進行編程才能真正實現(xiàn)郵件類軟件產(chǎn)品和服務的開放性和標準化。本文著重對SMTP協(xié)議及其在VC++編程中的應用做了介紹,并按照SMTP協(xié)議對電子郵件的發(fā)送進行了開放性和標準性較好的程序設計。本文所述程序在Windows 98下,由Microsoft Visual C++ 6.0編譯通過。
,
posted on 2010-10-11 14:05 我風 閱讀(1428) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


<2011年6月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

常用鏈接

留言簿(12)

隨筆分類

隨筆檔案

文章檔案

相冊

收藏夾

C++

MyFavorite

搜索

  •  

積分與排名

  • 積分 - 328996
  • 排名 - 75

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一区综合| 日韩网站在线观看| 国产精品日韩一区二区三区| 欧美久久99| 欧美国产精品va在线观看| 欧美成人精品不卡视频在线观看| 久久狠狠亚洲综合| 久久久噜噜噜久久狠狠50岁| 欧美成人免费va影院高清| 欧美成人乱码一区二区三区| 欧美日韩另类字幕中文| 国产精品一区二区在线观看不卡| 国产日韩欧美一区二区三区四区| 在线视频欧美日韩精品| 久久国产成人| 亚洲欧美另类国产| 欧美在线日韩| 欧美激情视频在线播放| 一区二区三区导航| 欧美性视频网站| 欧美高清成人| 在线性视频日韩欧美| 在线视频免费在线观看一区二区| 欧美一区不卡| 欧美激情视频在线播放| 国产日韩精品视频一区| 亚洲毛片在线看| 久久久久国产精品人| 亚洲国产精品久久久久秋霞蜜臀| 亚洲福利在线视频| 亚洲欧美综合国产精品一区| 久热综合在线亚洲精品| 国产精品欧美一区二区三区奶水| 亚洲国产精品高清久久久| 欧美一级电影久久| 亚洲激情视频| 久久综合久久久久88| 国产精品一区2区| 一本色道久久综合亚洲精品不 | 这里只有精品丝袜| 久久精品国产欧美亚洲人人爽| 欧美日韩成人一区| 一区在线播放| 久久久久久久尹人综合网亚洲| 亚洲少妇诱惑| 欧美精品一区二区三区一线天视频| 欧美一级夜夜爽| 亚洲综合日本| 欧美成人三级在线| 欧美一区二区三区在线看| 欧美国产一区二区三区激情无套| 一区二区三区无毛| 久久香蕉精品| 欧美一区2区三区4区公司二百| 国产精品福利在线观看网址| 亚洲深夜福利视频| 亚洲级视频在线观看免费1级| 久久久久一区二区三区四区| 国产亚洲精品v| 久久成人av少妇免费| 亚洲图片激情小说| 国产精品久久久久aaaa九色| 午夜激情综合网| 亚洲免费影视| 国内精品久久久久伊人av| 久久久久久久久久久久久女国产乱| 香蕉精品999视频一区二区| 国产精品综合色区在线观看| 欧美一级午夜免费电影| 欧美怡红院视频| 黄色成人av网站| 久久综合给合| 久久综合伊人77777麻豆| 亚洲国产精品久久久久| 欧美激情视频一区二区三区免费| 欧美承认网站| 亚洲一区二区在线看| 亚洲欧美中文在线视频| 国产综合视频| 亚洲国产精品成人| 欧美日本一区| 性做久久久久久久久| 香蕉亚洲视频| 亚洲精品少妇30p| 国产精品99久久久久久久vr | 久久久久高清| 亚洲大黄网站| 99在线热播精品免费99热| 亚洲一区激情| 亚洲人成网站影音先锋播放| 亚洲一二三四区| 亚洲黄色大片| 欧美日韩1080p| 久久激情中文| 欧美日韩一区三区| 久久久久久久久久看片| 欧美日韩成人一区| 久久午夜精品一区二区| 欧美另类女人| 久久久久久亚洲精品中文字幕| 欧美福利视频在线| 久久精品亚洲| 欧美日本视频在线| 乱码第一页成人| 国产精品扒开腿做爽爽爽视频| 久久爱91午夜羞羞| 新67194成人永久网站| 亚洲伦理自拍| 亚洲二区在线视频| 亚洲自拍偷拍视频| 亚洲经典三级| 性高湖久久久久久久久| 一区二区日韩免费看| 久久精品天堂| 欧美一区二区三区视频免费| 欧美高清在线一区二区| 久久亚洲综合网| 国产伦精品一区二区三区照片91| 亚洲精品黄色| 亚洲国产日韩在线| 久久狠狠婷婷| 久久精品人人做人人综合| 国产精品v欧美精品∨日韩| 欧美大片在线看| 永久免费精品影视网站| 久久国产精品72免费观看| 久久久无码精品亚洲日韩按摩| 久久精品国产69国产精品亚洲| 国产精品一区二区三区四区| 一区二区黄色| 亚洲一区二区综合| 国产精品久久91| 亚洲视频在线观看三级| 一区二区免费在线播放| 美女诱惑一区| 亚洲国产99| a4yy欧美一区二区三区| 欧美日韩国产在线看| 亚洲免费观看高清完整版在线观看熊| 亚洲精品久久久蜜桃| 米奇777在线欧美播放| 欧美激情精品久久久久| 亚洲日韩中文字幕在线播放| 欧美精品免费在线观看| 一区二区三区四区精品| 校园激情久久| 国产精品久久久久久久9999| 亚洲天堂成人在线观看| 亚洲欧美在线视频观看| 国产精品一区二区在线观看网站| 亚洲乱码国产乱码精品精可以看| 亚洲一区视频在线观看视频| 国产精品视频你懂的| 久久国产精品毛片| 免费成人高清| 夜夜嗨av色一区二区不卡| 国产精品视频网站| 羞羞色国产精品| 欧美wwwwww| 亚洲一二三区在线| 国产视频一区在线观看| 久久综合给合| 一本色道久久综合亚洲精品婷婷 | 六十路精品视频| 加勒比av一区二区| 欧美日韩国产综合一区二区| 亚洲欧美欧美一区二区三区| 蜜臀av在线播放一区二区三区| 久久久久久有精品国产| 亚洲福利视频一区| 午夜精品视频在线| 亚洲高清在线播放| 亚洲主播在线观看| **网站欧美大片在线观看| 欧美成人dvd在线视频| 亚洲综合激情| 91久久精品日日躁夜夜躁国产| 国产精品成人一区二区| 久久天天躁夜夜躁狠狠躁2022| 亚洲欧美成人一区二区在线电影 | 日韩一级大片在线| 久久夜色精品国产| 亚洲综合成人婷婷小说| 亚洲第一中文字幕在线观看| 国产精品av免费在线观看| 美日韩丰满少妇在线观看| 欧美一区1区三区3区公司| 夜夜嗨av色综合久久久综合网| 欧美在线视频免费观看| 99riav国产精品| 一区在线免费| 国产日产亚洲精品| 国产精品乱码| 欧美日韩亚洲一区二区三区| 美国成人毛片| 久久亚洲私人国产精品va| 午夜精品一区二区三区在线播放| 亚洲理论在线观看| 亚洲国产va精品久久久不卡综合| 久久精品女人|