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;
}
原文地址:https://www.cnblogs.com/chechen/p/6956066.html