zoukankan      html  css  js  c++  java
  • C++使用Socket 邮箱登录服务器验证

    转载:http://blog.csdn.net/zengraoli/article/details/36866241

    转载:http://blog.csdn.net/alger_magic/article/details/25164187

    一、如果想单纯验证一个邮箱帐号是否存在,我们可以拿邮箱帐号和密码请求服务器验证。

    .h文件

    #ifndef _AUTHENTICATIONEMAIL_H_
    #define _AUTHENTICATIONEMAIL_H_
    
    #include <atlenc.h>
    #include <winsock2.h>
    
    #pragma comment(lib, "wsock32.lib")
    
    
    struct sMailInfo                    //邮件信息
    {
        char *mailbox_user_name;        //用户登录邮箱的名称
        char *mailbox_user_pwd;            //用户登录邮箱的密码
        char *mailbox_sender_show_name;    //用户发送时显示的名称
        char *mailbox_sender;            //发送者的邮箱地址
        char *mailbox_receiver;            //接收者的邮箱地址
        char mail_server_ip_addr[32];    //服务器的IP
        char *mail_server_name;            //服务器的名称(IP与名称二选一,优先取名称)
        sMailInfo() { memset(this, 0, sizeof(sMailInfo)); }
    };
    
    class CAuthentic
    {
    public:
        CAuthentic();
    
        ~CAuthentic();
    
        void Char2Base64(char *buff_64, char *src_buff, int length);//把char类型转换成Base64类型
    
        bool CReateSocket(SOCKET &sock);            //建立socket连接
    
        bool Login(SOCKET &sock);                    //登录邮箱,主要进行发邮件前的准备工作
    
        void Init(sMailInfo &smail_info);
    
    protected:
        char  send_buff_[4096];                        //发送缓冲区
        char  receive_buff_[1024];
        sMailInfo mail_info_;
    };

    .cpp文件

    #include "AuthenticationEmail.h"
    #pragma warning(disable:4996)
    
    CAuthentic::CAuthentic()
    {
        memset(send_buff_, 0, sizeof(send_buff_));
        memset(receive_buff_, 0, sizeof(receive_buff_));
    }
    
    CAuthentic::~CAuthentic()
    {
    
    }
    
    void CAuthentic::Char2Base64(char *buff_64, char *src_buff, int length)
    {
        //1   1   1   1   1   1   1   1
        // 分配给pBuff64  ↑ 分配给pBuff64+1
        // point所在的位置
        static char base_64_encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";//base64所映射的字符表
        int point;        // 每一个源字符拆分的位置,可取2,4,6;初始为2
        point = 2;
        int base_index; // base64字符的索引
        char n = 0;        // 上一个源字符的残留值
        for(int index = 0; index < length; index++)
        {
            if(point == 2)
            {
                base_index = ((*src_buff) >> point) & 0x3f; // 取得pSrcBuff的高point位
            }
            else if (point == 4)
            {
                base_index = ((*src_buff) >> point) & 0xf;    // 取得pSrcBuff的高point位
            }
            else if(point == 6)
            {
                base_index = ((*src_buff) >> point) & 0x3;    // 取得pSrcBuff的高point位
            }
            base_index += n;                                // 与pSrcBuff-1的低point结合组成Base64的索引
            *buff_64++ = base_64_encode[base_index];        // 由索引表得到pBuff64
            n = ((*src_buff) << (6 - point));                // 计算源字符中的残留值
            n = n & 0x3f;                                    //确保n的最高两位为0
            point += 2;                                        //源字符的拆分位置上升2
            if(point == 8)        //如果拆分位置为8说明pSrcBuff有6位残留,可以组成一个完整的Base64字符,所以直接再组合一次
            {
                base_index = (*src_buff) & 0x3f;            //提取低6位,这就是索引了
                *buff_64++ =base_64_encode[base_index];
                n = 0;            // 残留值为0
                point = 2;        // 拆分位置设为2
            }
            src_buff++;
    
        }
        if(n != 0)
        {
            *buff_64++ = base_64_encode[n];
        }
        if(length % 3  == 2)    // 如果源字符串长度不是3的倍数要用'='补全
        {
            *buff_64 = '=';
        }
        else if(length % 3 == 1)
        {
            *buff_64++ = '=';
            *buff_64 = '=';
        }
    }
    
    bool CAuthentic::CReateSocket(SOCKET &sock)
    {
        WORD wVersionRequested;
        WSADATA wsaData;
        int err;
        wVersionRequested = MAKEWORD( 2, 2 );
        err = WSAStartup(wVersionRequested, &wsaData);
        if (err != 0) 
        {
            return false;
        }
        if (LOBYTE(wsaData.wVersion) != 2 ||
            HIBYTE(wsaData.wVersion) != 2 )
        {
            WSACleanup();
            return false; 
        }
        sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
        if (sock == INVALID_SOCKET)
        {
            return false;
        }
    
        sockaddr_in server_addr;
        memset(&server_addr, 0, sizeof(sockaddr_in));
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(25);    // 发邮件一般都是25端口,SSL的是465端口
        if(mail_info_.mail_server_name == "")
        {
            server_addr.sin_addr.s_addr = inet_addr(mail_info_.mail_server_ip_addr);    // 直接使用IP地址
        }
        else
        {
            struct hostent *hp = gethostbyname(mail_info_.mail_server_name);    // 使用名称
            server_addr.sin_addr.s_addr = *(int*)(*hp->h_addr_list);
            char* ip = inet_ntoa(server_addr.sin_addr);
            strcpy(mail_info_.mail_server_ip_addr, ip);
        }
    
    
        int ret = connect(sock, (sockaddr*)&server_addr, sizeof(server_addr));    // 建立连接
        if (ret == SOCKET_ERROR)
        {
            return false;
        }
    
        return true;
    }
    
    bool CAuthentic::Login(SOCKET &sock)
    {
        recv(sock, receive_buff_, 1024, 0);
    
        memset(send_buff_, 0, sizeof(send_buff_));
        sprintf_s(send_buff_, "HELO %s
    ", mail_info_.mail_server_ip_addr);
        send(sock,send_buff_, strlen(send_buff_), 0);    // 开始会话
        memset(receive_buff_, 0, sizeof(receive_buff_));
        recv(sock,receive_buff_, 1024, 0);
        if(receive_buff_[0] != '2' || receive_buff_[1] != '5' || receive_buff_[2] != '0')
        {
            return false;
        }
    
        memset(send_buff_, 0, sizeof(send_buff_));
        sprintf_s(send_buff_, "AUTH LOGIN
    ");
        send(sock,send_buff_, strlen(send_buff_),0);    // 请求登录
        recv(sock,receive_buff_, 1024, 0);
        if(receive_buff_[0] != '3' || receive_buff_[1] != '3' || receive_buff_[2] != '4')
        {
            return false;
        }
    
        memset(send_buff_, 0, sizeof(send_buff_));
        Char2Base64(send_buff_, mail_info_.mailbox_user_name, strlen(mail_info_.mailbox_user_name));
        send_buff_[strlen(send_buff_)] = '
    ';
        send_buff_[strlen(send_buff_)] = '
    ';
        send(sock,send_buff_, strlen(send_buff_), 0);    // 发送用户名
        recv(sock,receive_buff_, 1024, 0);
        if(receive_buff_[0] != '3' || receive_buff_[1] != '3' || receive_buff_[2] != '4')
        {
            return false;
        }
    
        memset(send_buff_, 0, sizeof(send_buff_));
        Char2Base64(send_buff_, mail_info_.mailbox_user_pwd, strlen(mail_info_.mailbox_user_pwd));
        send_buff_[strlen(send_buff_)] = '
    ';
        send_buff_[strlen(send_buff_)] = '
    ';
        send(sock, send_buff_, strlen(send_buff_), 0);    // 发送用户密码
        recv(sock, receive_buff_, 1024, 0);
        if(receive_buff_[0] != '2' || receive_buff_[1] != '3' || receive_buff_[2] != '5')
        {
            return false;
        }
        return true;    // 登录成功
    }
    
    void CAuthentic::Init(sMailInfo &smail_info)
    {
        memcpy(&mail_info_, &smail_info, sizeof(smail_info));
    }

    二、测试使用

       这里我用的163来测试,具体换成存在的邮箱测试

    #include "AuthenticationEmail.h"
    
    //验证邮箱
    void Authenticate()
    {
        CSendMail mail;
        sMailInfo info;
    
    
        info.mail_server_name = "smtp.163.com";//邮件服务器名称
        info.mailbox_receiver = "receiver@qq.com";//收件人邮箱帐号
        info.mailbox_sender = "sender@163.com";//发送者邮箱帐号
        info.mailbox_user_name = "sendername";//发送者名字
        info.mailbox_user_pwd = "xxxxxxxxx";//发送者邮箱密码
    
    
        mail.Init(info);
    
    
        SOCKET sock;
         // 建立连接
        if(mail.CReateSocket(sock))
        {
            if(mail.Logon(sock))        // 登录邮箱
            {
                ::MessageBox(NULL,_T("验证成功"),_T("tip"),MB_OK);
            }
        }
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        Authenticate();
        
        return 0;
    }
  • 相关阅读:
    5.共享文件夹
    4.CentOS安装
    JS 递归
    Gulp 笔记
    Js call apply bind区别
    Js new 过程解析
    Js 原型和原型链
    JS blur和click 顺序冲突
    重新认识button disabled属性
    英语笔记3
  • 原文地址:https://www.cnblogs.com/chechen/p/6956066.html
Copyright © 2011-2022 走看看