SMTP.CPP
上传用户:sanlisteel
上传日期:2008-06-19
资源大小:98k
文件大小:6k
源码类别:

数据库系统

开发平台:

C/C++

  1. // SMTP.cpp: implementation of the CSMTP class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "SMTP.h"
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char THIS_FILE[]=__FILE__;
  9. #define new DEBUG_NEW
  10. #endif
  11. CSMTP::response_code CSMTP::response_table[] =
  12. {
  13. // GENERIC_SUCCESS
  14. { 250, _T( "SMTP服务器错误" ) },
  15. // CONNECT_SUCCESS
  16. { 220, _T( "SMTP服务器不可用" ) },
  17. // DATA_SUCCESS
  18. { 354, _T( "SMTP服务器不能接收数据" ) },
  19. // QUIT_SUCCESS
  20. { 221, _T( "SMTP没有中止会话" ) }
  21. };
  22. //////////////////////////////////////////////////////////////////////
  23. // Construction/Destruction
  24. //////////////////////////////////////////////////////////////////////
  25. CSMTP::CSMTP( LPCTSTR szSMTPServerName, UINT nPort )
  26. {
  27. ASSERT( szSMTPServerName != NULL );
  28. AfxSocketInit();    //初始化Windows Sockets类的使用
  29. m_sSMTPServerHostName = szSMTPServerName;
  30. m_nPort = nPort;
  31. m_bConnected = FALSE;
  32. m_sError = _T( "OK" );
  33. response_buf = NULL;
  34. }
  35. CSMTP::~CSMTP()
  36. {
  37. Disconnect();   //断开连接
  38. }
  39. CString CSMTP::GetServerHostName()
  40. {
  41. return m_sSMTPServerHostName;
  42. }
  43. //建立到服务器的连接
  44. BOOL CSMTP::Connect()
  45. {
  46. CString sHello;
  47. TCHAR local_host[ 80 ];
  48. if( m_bConnected )
  49. return TRUE;
  50. try
  51. {
  52. response_buf = new TCHAR[ RESPONSE_BUFFER_SIZE ];
  53. if( response_buf == NULL )
  54. {
  55. m_sError = _T( "内存不足!" );
  56. return FALSE;
  57. }
  58. }
  59. catch( CException *e )    //使用基类进行捕捉
  60. {      
  61. response_buf = NULL;
  62. m_sError = _T( "内存不足!" );
  63. delete e;
  64. return FALSE;
  65. }
  66. if( !m_wsSMTPServer.Create() )
  67. {
  68. m_sError = _T( "无法创建套接字!" );
  69. delete response_buf;
  70. response_buf = NULL;
  71. return FALSE;
  72. }
  73. if( !m_wsSMTPServer.Connect( GetServerHostName(), GetPort() ) )
  74. {
  75. m_sError = _T( "无法连接到服务器" );
  76. m_wsSMTPServer.Close();
  77. delete response_buf;
  78. response_buf = NULL;
  79. return FALSE;
  80. }
  81. if( !get_response( CONNECT_SUCCESS ) )  
  82. {
  83. m_sError = _T( "服务器没有响应" );
  84. m_wsSMTPServer.Close();
  85. delete response_buf;
  86. response_buf = NULL;
  87. return FALSE;
  88. }
  89. gethostname( local_host, 80 );   //得到本地机器标准主机名
  90. sHello.Format( _T( "HELO %srn" ), local_host );
  91. m_wsSMTPServer.Send( (LPCTSTR)sHello, sHello.GetLength() );  //建立连接后发送数据
  92. if( !get_response( GENERIC_SUCCESS ) )
  93. {
  94. m_wsSMTPServer.Close();
  95. delete response_buf;
  96. response_buf = NULL;
  97. return FALSE;
  98. }
  99. m_bConnected = TRUE;
  100. return TRUE;
  101. }
  102. //断开连接
  103. BOOL CSMTP::Disconnect()
  104. {
  105. BOOL ret;
  106. if( !m_bConnected )
  107. return TRUE;
  108. CString sQuit = _T( "QUITrn" );
  109. m_wsSMTPServer.Send( (LPCTSTR)sQuit, sQuit.GetLength() );
  110. ret = get_response( QUIT_SUCCESS );
  111. m_wsSMTPServer.Close();
  112. if( response_buf != NULL )
  113. {
  114. delete[] response_buf;
  115. response_buf = NULL;
  116. }
  117. m_bConnected = FALSE;
  118. return ret;
  119. }
  120. //取得SMTP服务器端口号
  121. UINT CSMTP::GetPort()
  122. {
  123. return m_nPort;
  124. }
  125. //取得错误信息
  126. CString CSMTP::GetLastError()
  127. {
  128. return m_sError;
  129. }
  130. //发邮件到服务器
  131. BOOL CSMTP::SendMessage(CMailMessage * msg)
  132. {
  133. ASSERT( msg != NULL );
  134. if( !m_bConnected )
  135. {
  136. m_sError = _T( "必须首先创建连接!" );
  137. return FALSE;
  138. }
  139. if( FormatMailMessage( msg ) == FALSE )
  140. {
  141. return FALSE;
  142. }
  143. if( transmit_message( msg ) == FALSE )
  144. {
  145. return FALSE;
  146. }
  147. return TRUE;
  148. }
  149. //格式化邮件信息
  150. BOOL CSMTP::FormatMailMessage( CMailMessage* msg )
  151. {
  152. ASSERT( msg != NULL );
  153. if( msg->GetNumRecipients() == 0 )
  154. {
  155. m_sError = _T( "No Recipients" );
  156. return FALSE;
  157. }
  158. msg->FormatMessage();
  159. return TRUE;
  160. }
  161. //配置服务器
  162. void CSMTP::SetServerProperties( LPCTSTR szSMTPServerName, UINT nPort)
  163. {
  164. ASSERT( szSMTPServerName != NULL );
  165. if( szSMTPServerName == NULL )
  166. return;
  167. m_sSMTPServerHostName = szSMTPServerName;
  168. m_nPort = nPort;
  169. }
  170. //获得邮件体得到发送内容
  171. CString CSMTP::cook_body(CMailMessage * msg)
  172. {
  173. ASSERT( msg != NULL );
  174. CString sTemp;
  175. CString sCooked = _T( "" );
  176. LPTSTR szBad = _T( "rn.rn" );
  177. LPTSTR szGood = _T( "rn..rn" );
  178. int nPos;
  179. int nStart = 0;
  180. int nBadLength = strlen( szBad );
  181. sTemp = msg->m_sBody;
  182. if( sTemp.Left( 3 ) == _T( ".rn" ) )
  183. sTemp = _T( "." ) + sTemp;
  184. while( (nPos = sTemp.Find( szBad )) > -1 )
  185. {
  186. sCooked = sTemp.Mid( nStart, nPos );
  187. sCooked += szGood;
  188. sTemp = sCooked + sTemp.Right( sTemp.GetLength() - (nPos + nBadLength) );
  189. }
  190. return sTemp;
  191. }
  192. //发送邮件
  193. BOOL CSMTP::transmit_message(CMailMessage * msg)
  194. {
  195. CString sFrom;
  196. CString sTo;
  197. CString sTemp;
  198. CString sEmail;
  199.     CString sSubject;
  200. ASSERT( msg != NULL );
  201. if( !m_bConnected )
  202. {
  203. m_sError = _T( "必须首先创建连接!" );
  204. return FALSE;
  205. }
  206. sFrom.Format( _T( "MAIL From: <%s>rn" ), (LPCTSTR)msg->m_sFrom );
  207. m_wsSMTPServer.Send( (LPCTSTR)sFrom, sFrom.GetLength() );
  208. if( !get_response( GENERIC_SUCCESS ) )
  209. return FALSE;
  210. for( int i = 0; i < msg->GetNumRecipients(); i++ )
  211. {
  212. msg->GetRecipient( sEmail, sTemp, i );
  213. sTo.Format( _T( "RCPT TO: <%s>rn" ), (LPCTSTR)sEmail );
  214. m_wsSMTPServer.Send( (LPCTSTR)sTo, sTo.GetLength() );
  215. get_response( GENERIC_SUCCESS );
  216. }
  217. sTemp = _T( "DATArn" );
  218. m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() );
  219. if( !get_response( DATA_SUCCESS ) )
  220. {
  221. return FALSE;
  222. }
  223. sSubject.Format( _T( "SUBJECT: <%s>rn" ), (LPCTSTR)msg->m_sSubject );
  224. m_wsSMTPServer.Send( (LPCTSTR)sSubject, sSubject.GetLength() );
  225. // m_wsSMTPServer.Send( (LPCTSTR)msg->m_sHeader, msg->m_sHeader.GetLength() );
  226. sTemp = cook_body( msg );
  227. m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() );
  228. sTemp = _T( "rn.rn" );
  229. m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() );
  230. if( !get_response( GENERIC_SUCCESS ) )
  231. {
  232. return FALSE;
  233. }
  234. return TRUE;
  235. }
  236. //得到服务器响应
  237. BOOL CSMTP::get_response( UINT response_expected )
  238. {
  239. ASSERT( response_expected >= GENERIC_SUCCESS );
  240. ASSERT( response_expected < LAST_RESPONSE );
  241. CString sResponse;
  242. UINT response;
  243. response_code* pResp;
  244. if( m_wsSMTPServer.Receive( response_buf, RESPONSE_BUFFER_SIZE ) == SOCKET_ERROR )
  245. {
  246. m_sError = _T( "套接字错误!" );
  247. return FALSE;
  248. }
  249. sResponse = response_buf;
  250. sscanf( (LPCTSTR)sResponse.Left( 3 ), _T( "%d" ), &response );
  251. pResp = &response_table[ response_expected ];
  252. if( response != pResp->nResponse )
  253. {
  254. m_sError.Format( _T( "%d:%s" ), response, (LPCTSTR)pResp->sMessage );
  255. return FALSE;
  256. }
  257. return TRUE;
  258. }