[转]smtp邮件发送程序

公司要做一个邮件发送程序,把程序中生成的报告发送到管理员的邮箱,由于考虑到不能使用邮件客户端,只好自己从smtp协议写起,这一路写来是相当郁闷。以新浪的smtp.sina.com为目标。
在这个网址上有个简单的邮件发送程序
http://www.codeproject.com/KB/IP/zsmtp.aspx#xx1394512xx
是在网上搜到的第一个最有用的程序,但他没有提供登录验证功能。经我该进登录验证,发送邮件代码如下:
说明:先用thundbird利用smtp.sina.com发了一封,用Ultra Network Sniffer截了smtp的包,用程序来发一样的命令序列到新浪服务器上,除最后的那个QUIT/r/n 命令服务器没有回复外,其余的命令都得到了和thundbird一样的回复,但是邮件没有发送成功,超级郁闷。如果谁在这方面有经验,请指教。或者有意研究的人,加我QQ:254909662我把工程文件传给你。工程文件是在VS2005下的。最后我只好用jmail邮件包来发送,程序是用c++写的,十分简单。我将贴在这个日志的最后。
这个是用thundbird发smtp.sina.com的命令序列:表示客户端发送
<----220 irxd5-202.sinamail.sina.com.cn ESMTP/r/n
--->EHLO [127.0.0.1]/r/n
<----250-irxd5-202.sinamail.sina.com.cn/r/n
<---250-8BITMIME/r/n250-SIZE 31457280/r/n250-AUTH PLAIN LOGIN/r/n250 AUTH=PLAIN LOGIN/r/n
--->AUTH PLAIN AGRp 注:此处省略了一些字母(密码)
<--- 235 #2.0.0 OK Authenticated/r/n
--->MAIL FROM: SIZE=315/r/n
ok/r/n
--->RCPT TO:/r/n
ok/r/n
--->DATA/r/n
<---354 Send from Rising mail proxy/r/n
---->Message-ID:
      Date: Thu, 26 Feb 2009 13:01:31 +0800
      From: digua
      User-Agent: Thunderbird 2.0.0.19 (Windows/20081209)
      MIME-Version: 1.0
      To: digua254909662@163.com
      Subject: bt
      Content-Type: text/plain; charset=GB2312
      Content-Transfer-Encoding: 7bit/r/n/r/ntest/r/n ./r/n
<---250
--->/r/nQUIT/r/n
<---221 irxd5-202.sinamail.sina.com.cn/r/n
下面是我的代码:
SOCKET CFastSmtp::_connectServerSocket(const char server[],
                                       const unsigned short port)
{
    int                nConnect;
    short            nProtocolPort;
    LPHOSTENT        lpHostEnt;
    LPSERVENT        lpServEnt;
    SOCKADDR_IN        sockAddr;       
    SOCKET            hServerSocket = INVALID_SOCKET;
    lpHostEnt = gethostbyname(server);
    if (lpHostEnt) {       
        hServerSocket = socket(PF_INET, SOCK_STREAM,DEFAULT_PROTOCOL);
        if (hServerSocket != INVALID_SOCKET) {
            if (port != NULL) {
                nProtocolPort = port;
            }else{
                lpServEnt = getservbyname("mail", DEFAULT_PROTOCOL);
                if (lpServEnt == NULL)
                    nProtocolPort = htons(IPPORT_SMTP);
                else
                    nProtocolPort = lpServEnt->s_port;
            }
            sockAddr.sin_family = AF_INET;
            sockAddr.sin_port = nProtocolPort;
            sockAddr.sin_addr = *((LPIN_ADDR)*lpHostEnt->h_addr_list);
            nConnect = connect(hServerSocket, (PSOCKADDR)&sockAddr,
                               sizeof(sockAddr));
            if(nConnect)
            {
                hServerSocket = INVALID_SOCKET;
                std::cout <<"connect to server failed" <                return hServerSocket;
            }
            char sReceiveBuffer[MAX_BUFFER_SIZE];
            int  recvLength;
            if( (recvLength = recv(hServerSocket, (LPSTR)sReceiveBuffer, MAX_BUFFER_SIZE, NO_FLAGS) ) < 0)
            {
                return (hServerSocket = INVALID_SOCKET);
            }
            std::string response(sReceiveBuffer, recvLength);
            std::cout <<"REC(" <<"220" <<")" <            if( response.substr(0, 3) != "220")
            {
                return (hServerSocket = INVALID_SOCKET);
            }
        } else {
            printf("Invalid socket/r/n");
            throw;
        }
    }
    return(hServerSocket);
}
bool CFastSmtp::ConnectServer(const char server[], const unsigned short port)
{
    assert(server);
    if (bCon)
        Disconnect();
    bCon=false;
    hSocket = INVALID_SOCKET;
    hSocket = _connectServerSocket(server, port);   
    if (hSocket != INVALID_SOCKET)
    {
        if( !simulateThundBird())
            return false;
    } else
    {
        printf("Invalid socket/r/n");
        return (false);
    }
    bCon=true;
    return (true);
}
bool CFastSmtp::simulateThundBird()
{
    std::string msg;
    msg = "EHLO [127.0.0.1]/r/n";
    std::cout <<"Send:" <<"(" <    if (send(hSocket, (LPSTR)msg.c_str(), msg.length(), NO_FLAGS) == SOCKET_ERROR)
    {
        printf("Socket send error: %d/r/n", WSAGetLastError());   
        return (false);
    }
    if( !rcvResponse("250"))
        return false;
    if( !rcvResponse("250"))
        return false;
    /*if( !rcvResponse("250"))
        return false;
    if( !rcvResponse("250"))
        return false;
    if( !rcvResponse("250"))
        return false;*/
    msg = "AUTH PLAIN AGRpMTQ1Njk1/r/n";这个是用thundbird发是截的数据,我删除了一些(涉及到邮箱密码)
    std::cout <<"Send:" <<"(" <    if (send(hSocket, (LPSTR)msg.c_str(), msg.length(), NO_FLAGS) == SOCKET_ERROR)
    {
        printf("Socket send error: %d/r/n", WSAGetLastError());   
        return (false);
    }
    if( !rcvResponse("235"))
        return false;
    return true;
}
bool CFastSmtp::Send()
{
// verify sender email
    if (m_pcFromEmail == NULL) {
        printf("Please specifiy a sender email address/r/n");
        return (false);
    }
    BYTE        sReceiveBuffer[4096];
    int            iLength = 0;
    int            iEnd = 0;
    char        buf[4096];
// get proper header
    char* msgHeader = _formatHeader();
    if (msgHeader == NULL) {
        delete [] msgHeader;
        printf("Failed to format message header/r/n");
        return (false);
    }
// start
    strcpy(buf, "MAIL FROM: <");
    strcat(buf, m_pcFromEmail);
    strcat(buf, "> SIZE=316/r/n"); //这个316是我用thundbird发邮件截的,这个代码发和thundbird相同的邮件
    std::cout <<"Send:" <<"(" <    if (send(hSocket, (LPSTR)buf, strlen(buf), NO_FLAGS) == SOCKET_ERROR) {
        printf("Socket send error: %d/r/n", WSAGetLastError());   
        return (false);
    }
    if( !rcvResponse("250"))
    {
        return false;
    }
// create message receipts
    char *token;
    for(unsigned int i=0;i    {
        token = strtok(Recipients.at(i)->GetEmail(),"<");
        token = strtok(NULL,"<");   
        if (token == NULL)
            token = strtok(Recipients.at(i)->GetEmail(),"<");
        strcpy(buf, "RCPT TO: <");
        strcat(buf, token);
        strcat(buf, "/r/n");
        std::cout <<"Send:" <<"(" <        if (send(hSocket, (LPSTR)buf, strlen(buf), NO_FLAGS) == SOCKET_ERROR) {
            printf("Socket send error: %d/r/n", WSAGetLastError());   
            return (false);
        }
        if( !rcvResponse("250"))
        {
            return false;
        }
    }
    for(unsigned int i=0;i        token = strtok(CCRecipients.at(i)->GetEmail(),"<");
        token = strtok(NULL,"<");
        if (token == NULL)
            token = strtok(Recipients.at(i)->GetEmail(),"<");
        strcpy(buf, "RCPT TO: <");
        strcat(buf, token);
        strcat(buf, "/r/n");
        std::cout <<"Send:" <<"(" <        if (send(hSocket, (LPSTR)buf, strlen(buf), NO_FLAGS) == SOCKET_ERROR) {
            printf("Socket send error: %d/r/n", WSAGetLastError());   
            return (false);
        }
        if( !rcvResponse("250"))
        {
            return false;
        }
    }
    for(unsigned int i=0;i        token = strtok(BCCRecipients.at(i)->GetEmail(),"<");
        token = strtok(NULL,"<");
        if (token == NULL)
            token = strtok(Recipients.at(i)->GetEmail(),"<");
        strcpy(buf, "RCPT TO: <");
        strcat(buf, token);
        strcat(buf, "/r/n");
        std::cout <<"Send:" <<"(" <        if (send(hSocket, (LPSTR)buf, strlen(buf), NO_FLAGS) == SOCKET_ERROR) {
            printf("Socket send error: %d/r/n", WSAGetLastError());   
            return (false);
        }
        if( !rcvResponse("250"))
        {
            return false;
        }
        /*iLength = recv(hSocket, (LPSTR)sReceiveBuffer+iEnd,
                       sizeof(sReceiveBuffer)-iEnd,
                       NO_FLAGS);
        iEnd += iLength;
        sReceiveBuffer[iEnd] = '/0';*/
    }
// init data
    std::cout <<"Send:" <<"(" <<"DATA/r/n" <<")" <    if (send(hSocket, (LPSTR)"DATA/r/n", strlen("DATA/r/n"), NO_FLAGS) == SOCKET_ERROR) {
        printf("Socket send error: %d/r/n", WSAGetLastError());   
        return (false);
    }
    if( !rcvResponse("354"))
    {
        return false;
    }
// send header   
    std::cout <<"Send:" <<"(" <    if (send(hSocket,
             (LPSTR)msgHeader, strlen(msgHeader), NO_FLAGS) == SOCKET_ERROR) {
        printf("Socket send error: %d/r/n", WSAGetLastError());   
        delete [] msgHeader;
        return (false);
    }
// send body   
//    std::cout <<"Send:" <<"(" <//    if (send(hSocket,
//             (LPSTR)m_pcMsgBody, strlen(m_pcMsgBody), NO_FLAGS) == SOCKET_ERROR) {
//        printf("Socket send error: %d/r/n", WSAGetLastError());   
//        return (false);
//    }
signal end   
//
//    std::cout <<"Send:" <<"(" <<"/r/n./r/n" <<")" <//    if (send(hSocket,
//            (LPSTR)"/r/n./r/n", strlen("/r/n./r/n"), NO_FLAGS) == SOCKET_ERROR) {
//        printf("Socket send error: %d/r/n", WSAGetLastError());   
//        return (false);
//    }
    if( !rcvResponse("250"))
    {
        return false;
    }
    /*std::cout <<"Send:" <<"(" <<"/r/n" <<")" <    if (send(hSocket, (LPSTR)"/r/n", strlen("/r/n"), NO_FLAGS) == SOCKET_ERROR) {
        printf("Socket send error: %d/r/n", WSAGetLastError());   
        return (false);
    }*/
    std::cout <<"Send:" <<"(" <<"QUIT/r/n" <<")" <    if (send(hSocket, (LPSTR)"QUIT/r/n", strlen("QUIT/r/n"), NO_FLAGS) == SOCKET_ERROR) {
        printf("Socket send error: %d/r/n", WSAGetLastError());   
        return (false);
    }
    if( !rcvResponse("221"))
    {
        return false;
    }
    delete [] msgHeader;
    return (true);
}
用jmail从新浪smtp.sina.com发邮件到163的邮箱代码:
编译时把project->setting->c/c++ language下的把w_char当内置类型 改为否,要不会报不认识的符号:converttoBSTR错误。我用的是jmail4.5版本,http://www.vckbase.com/tools在这下的。安装目录里有教程。
#include
#import "../bin/jmail.dll"         // 导入jmail.dll, 假如jmail.dll不在工程目录下,您需要写上完整路径
#pragma comment(lib, "comsupp.lib")
void main()
{
    CoInitialize(NULL);     // COM的初始化
    {
        // 创建SpeedMailer实例
        jmail::IMessagePtr pMessage("JMail.Message");
        // 发件人邮箱
        pMessage->From = "username@sina.com";
        // 发件人姓名
        pMessage->FromName = "name";
        // 添加收件人1, 无收件人姓名与PGP KEY
        pMessage->AddRecipient("username@163.com","","");
        // 优先级设置,1-5逐次降低, 3为中级
        pMessage->Priority = 3;
        // 编码方式设置, 默认是iso-8859-1
        pMessage->Charset = "GB2312";
        // 主题
        pMessage->Subject = "bt";
        // 正文
        pMessage->Body = "test/r/n";
        pMessage->MailServerPassWord = "password";
        pMessage->MailServerUserName = "username";
        pMessage->Send("smtp.sina.com.cn", VARIANT_FALSE);
    }
    CoUninitialize();
    system("pause");
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值