谁能给一个收发mail的例子,通过socket和mapi都可以
解决方案 »
- 求教:关于OpenGL实现窗口Alpha通道的问题
- vs2008 ocx如何生成tlh文件
- VC8调试程序出报奇怪错误. Run-Time Check Failure #3 - The variable 'addrf' is being used without being initialized.
- 谁给解释下这段cfile代码?
- VC 内存DC画图保存成bmp的问题
- 数据库备份的问题
- 问个弱弱的问题:如何去掉对话框中的最大化按钮(现在是灰色)
- 一個小問題。windows2000 下寫的程式能不能直接在 window98下運行。如不能需要如何
- 如何对动态链接库进行资源共享????
- VC中怎样在ado动态创建数据库时候怎样判别时候已经创建数据库
- 我想做一个象QQ那样的一放到屏幕边就自动缩进,鼠标移到边上就自动弹出,请大家指点!
- 如何使第二个程序能调用第一个程序的计算结果呢?
2001年8月29日
有一段时间很多地方都在讨论如何写一个发送邮件的程序的问题,其实一个邮件发送程序
没有想象的那么难做,现在先简单讲一下怎样连接邮件服务器以及怎样做验证的过程。
首先创建一个socket,接下来连接你想要连接的发件服务器,连接上之后发送helo命令,
该命令的语法是helo <你的域名|你的IP>,之后分析接收到的返回串,返回字符串的前三位
是状态码,helo命令如果返回250就可以继续,否则就是有错误。接下来发送auth login命
令,如果返回码不是334,那么就是不需要验证,否则,注意!要将你的用户名和密码用
BASE64编码算法编码后分别发送过去,而不是直接发送。如果服务器返回状态码235就是验证
通过,不然就是用户名/密码有错误。下面是我连接smtp.263.net的过程(s:服务器 c:客户
端):s:220 smtp.263.net ESMTP
c:HELO mylocalhost
s:250 smtp.263.net
c:auth login
s:334 VXNlcm5hbWU6
c://我的用户名(已编码)
s:334 UGFzc3dvcmQ6
c://我的密码(已编码)
s:235 Authentication successful源代码:
[连接]
BOOL CSmtp::Connect()
{
CString sHello;
TCHAR local_host[80]; // Warning: arbitrary size
if(m_bConnected) return TRUE;try {
// This will be deleted in Disconnect();
response_buf = new TCHAR[RESPONSE_BUFFER_SIZE];
if(response_buf == NULL) {
m_sError = _T("Not enough memory");
return FALSE;
}
} catch(CException* e) {
response_buf = NULL;
m_sError = _T("Not enough memory");
delete e;
return FALSE;
}if(!m_wsSMTPServer.Create()) {
m_sError = _T("Unable to create the socket");
delete response_buf;
response_buf = NULL;
return FALSE;
}
if( !m_wsSMTPServer.Connect(m_sSMTPServerHostName, m_nPort)) {
m_sError = _T("Unable to connect to server");
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}
if(!get_response(CONNECT_SUCCESS)) {
m_sError = _T( "Server didn’t respond" );
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}
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)) {
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}
m_bConnected = TRUE;
return TRUE;
}[验证]
BOOL CSmtp::Auth()
{
CString sAuth;
if(!m_bConnected) return FALSE;sAuth.Format(_T( "auth login\r\n" )); //construct auth quest
m_wsSMTPServer.Send((LPCTSTR)sAuth, sAuth.GetLength());
if(!get_response(AUTHQUE_SUCCESS)) {
m_sError="SMTP server with no auth";
m_bAuthed=TRUE;
return TRUE;
}sAuth.Empty();sAuth.Format(_T( "%s\r\n" ), m_sSMTPUser); //is an string encoded with CBASE64
m_wsSMTPServer.Send((LPCTSTR)sAuth, sAuth.GetLength());
if(!get_response(AUTHQUE_SUCCESS)) {
m_sError="Unknown Error";
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}sAuth.Empty();sAuth.Format(_T( "%s\r\n" ), m_sSMTPPass); //is an string encoded with CBASE64
m_wsSMTPServer.Send((LPCTSTR)sAuth, sAuth.GetLength());
if(!get_response(AUTH_SUCCESS)) {
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}
m_bAuthed = TRUE;
return TRUE;
}
当上面的过程完成后,就完成了连接和验证的工作,可以开始准备发送邮件了。首先要使用的
是MAIL FROM:命令,格式"MAIL FROM: <发件人地址>",正常的返回码是250;这里要说的是有时上述命令会返回一个错误:553 Authentication is required to send mail as
[email protected]。出现这样的错误的原因是MAIL FROM发送过去的发件人地址里面包含的用户名
和你登陆发件服务器时使用的用户名不同,只需将二者统一就行了。接下来是RCPT TO:命令,
告诉服务器你想发给谁,格式和返回码同MAIL FROM。然后是DATA命令,没有参数,返回码
354;该命令送到之后就可以发送信件的内容了,内容结束的标志是<CRLF>.<CRLF>,用字符
串表示就是"\r\n.\r\n"。最后退出服务器的命令是QUIT,无参数,返回码221。c:MAIL FROM: [email protected]
s:250 smtp.263.net
c:RCPT TO: acesee.263.net
s:250 smtp.263.net
c:DATA
s:354 Start mail input; end with .
c://信件正文
c:<CRLF>.<CRLF>//正文结束
s:250 smtp.263.net
c:QUIT
s:221 Bye 源代码我就不在这里写了,太多了,请点击此处或到VC版下载仓库下载吧。