谁能给一个收发mail的例子,通过socket和mapi都可以

解决方案 »

  1.   

    简单邮件发送程序的设计制作 
    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版下载仓库下载吧。