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[]; //服务器的IP
char *mail_server_name; //服务器的名称(IP与名称二选一,优先取名称)
sMailInfo() { memset(this, , 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_[]; //发送缓冲区
char receive_buff_[];
sMailInfo mail_info_;
};
.cpp文件
#include "AuthenticationEmail.h"
#pragma warning(disable:4996) CAuthentic::CAuthentic()
{
memset(send_buff_, , sizeof(send_buff_));
memset(receive_buff_, , 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 = ;
int base_index; // base64字符的索引
char n = ; // 上一个源字符的残留值
for(int index = ; index < length; index++)
{
if(point == )
{
base_index = ((*src_buff) >> point) & 0x3f; // 取得pSrcBuff的高point位
}
else if (point == )
{
base_index = ((*src_buff) >> point) & 0xf; // 取得pSrcBuff的高point位
}
else if(point == )
{
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) << ( - point)); // 计算源字符中的残留值
n = n & 0x3f; //确保n的最高两位为0
point += ; //源字符的拆分位置上升2
if(point == ) //如果拆分位置为8说明pSrcBuff有6位残留,可以组成一个完整的Base64字符,所以直接再组合一次
{
base_index = (*src_buff) & 0x3f; //提取低6位,这就是索引了
*buff_64++ =base_64_encode[base_index];
n = ; // 残留值为0
point = ; // 拆分位置设为2
}
src_buff++; }
if(n != )
{
*buff_64++ = base_64_encode[n];
}
if(length % == ) // 如果源字符串长度不是3的倍数要用'='补全
{
*buff_64 = '=';
}
else if(length % == )
{
*buff_64++ = '=';
*buff_64 = '=';
}
} bool CAuthentic::CReateSocket(SOCKET &sock)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( , );
err = WSAStartup(wVersionRequested, &wsaData);
if (err != )
{
return false;
}
if (LOBYTE(wsaData.wVersion) != ||
HIBYTE(wsaData.wVersion) != )
{
WSACleanup();
return false;
}
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (sock == INVALID_SOCKET)
{
return false;
} sockaddr_in server_addr;
memset(&server_addr, , sizeof(sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(); // 发邮件一般都是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_, , ); memset(send_buff_, , sizeof(send_buff_));
sprintf_s(send_buff_, "HELO %s\r\n", mail_info_.mail_server_ip_addr);
send(sock,send_buff_, strlen(send_buff_), ); // 开始会话
memset(receive_buff_, , sizeof(receive_buff_));
recv(sock,receive_buff_, , );
if(receive_buff_[] != '' || receive_buff_[] != '' || receive_buff_[] != '')
{
return false;
} memset(send_buff_, , sizeof(send_buff_));
sprintf_s(send_buff_, "AUTH LOGIN\r\n");
send(sock,send_buff_, strlen(send_buff_),); // 请求登录
recv(sock,receive_buff_, , );
if(receive_buff_[] != '' || receive_buff_[] != '' || receive_buff_[] != '')
{
return false;
} memset(send_buff_, , sizeof(send_buff_));
Char2Base64(send_buff_, mail_info_.mailbox_user_name, strlen(mail_info_.mailbox_user_name));
send_buff_[strlen(send_buff_)] = '\r';
send_buff_[strlen(send_buff_)] = '\n';
send(sock,send_buff_, strlen(send_buff_), ); // 发送用户名
recv(sock,receive_buff_, , );
if(receive_buff_[] != '' || receive_buff_[] != '' || receive_buff_[] != '')
{
return false;
} memset(send_buff_, , sizeof(send_buff_));
Char2Base64(send_buff_, mail_info_.mailbox_user_pwd, strlen(mail_info_.mailbox_user_pwd));
send_buff_[strlen(send_buff_)] = '\r';
send_buff_[strlen(send_buff_)] = '\n';
send(sock, send_buff_, strlen(send_buff_), ); // 发送用户密码
recv(sock, receive_buff_, , );
if(receive_buff_[] != '' || receive_buff_[] != '' || receive_buff_[] != '')
{
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 ;
}
C++使用Socket 邮箱登录服务器验证的更多相关文章
- PHP用socket连接SMTP服务器发送邮件
PHP用socket连接SMTP服务器发送邮件 PHP用socket连接SMTP服务器发送邮件学习实验记录: 分析与SMTP会话的一般流程 1. HELO XXX \r\n //XXX就是自己起个名字 ...
- SuperMap-iServer-单点登录功能验证(CAS)
SuperMap-iServer-单点登录功能验证(CAS) 1.测试目的: 验证SuperMap-iServer使用CAS单点登录的功能是否正常. 2.测试环境: SuperMap-iServer8 ...
- SQLSERVER误删除了Windows登录用户验证方式使用Windows身份验证的解决方法
SQLSERVER误删Windows登录用户验证方式使用Windows身份验证的解决方法 今天看到这篇文章:没有了SA密码,无法Windows集成身份登录,DBA怎么办? 想起来之前着急哥问我的一个问 ...
- WebApi 登录身份验证
前言:Web 用户的身份验证,及页面操作权限验证是B/S系统的基础功能,一个功能复杂的业务应用系统,通过角色授权来控制用户访问,本文通过Form认证,Mvc的Controller基类及Action的权 ...
- net.sz.framework 框架 登录服务器架构 单服2 万 TPS(QPS)
前言 无论我们做什么系统,95%的系统都离不开注册,登录: 而游戏更加关键,频繁登录,并发登录,导量登录:如果登录承载不起来,那么游戏做的再好,都是徒然,进不去啊: 序言 登录所需要的承载,包含程序和 ...
- CAS单点登录服务器搭建
关于cas单点登录的原理及介绍这里不做说明了,直接开始: 1.war包下载 去官网(https://www.apereo.org/projects/cas/download-cas)下载cas_ser ...
- iptables log日志记录功能扩展应用:iptables自动配置临时访问策略,任意公网登录服务器
一.修改日志记录: 1. 修改配置文件: vi /etc/rsyslog.conf 添加以下内容 #iptables log kern.=notice /var/log/iptables.log 2. ...
- [转]python3之paramiko模块(基于ssh连接进行远程登录服务器执行命令和上传下载文件的功能)
转自:https://www.cnblogs.com/zhangxinqi/p/8372774.html 阅读目录 1.paramiko模块介绍 2.paramiko的使用方法 回到顶部 1.para ...
- 利用windows的计划任务和eKing.CmdReadFileAndSendEmailOper(控制台小程序)实现远程登录服务器的邮件告警提醒
一.场景摘要: 1.windows计划任务中,有一个用户登录时候触发的事件 2.cmd命令:netstat -ano | find "3389" 可以看到当前远程登录的IP 3 ...
随机推荐
- USB--- kvm in ubuntu:
USB SS=USB SuperSpeed=USB 3.0!!顺应此前的USB 1.1 FullSpeed和USB 2.0 HighSpeed https://jingyan.baidu.com/ar ...
- Catch---hdu3478(染色法判断是否含有奇环)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3478 题意:有n个路口,m条街,一小偷某一时刻从路口 s 开始逃跑,下一时刻都跑沿着街跑到另一路口,问 ...
- cookie的封装写法
设置cookie 三个参数分别代表:键,值,过期时间,这个封装方法可以完成cookie的储存 以及cookie的删除(过期时间设为赋值) function setCookie(cname,cval ...
- vue中 用媒体查询 空置根节点字体大小
在index.html中 <style> @media all and (min-width: 0px) { html{font-size: 20px;}/* 12*4.6 */ } @m ...
- kubernetes实战(十二):k8s使用helm持久化部署redmine集成openLDAP
1.基本概念 此次安装的有Jenkins.Gitlab.Redmine,我公司目前使用的是独立于k8s集群之外单独部署的Jenkins等服务,此文章会介绍三种服务基于k8s的部署方式,之后集成之前部署 ...
- javaScript高级教程(九) ------javascript对象字面量--------困扰已久的问题
在编程语言中,字面量是一种表示值的记法.例如,"Hello, World!" 在许多语言中都表示一个字符串字面量(string literal ),JavaScript也不例外. ...
- spring boot配置service发布服务
在application.yml中配置 server: port: 8080 context-path: /crm spring: datasource: driver-class-name: com ...
- Python 使用ctypes调用 C 函数
在python中通过ctypes可以直接调用c的函数,非常简单易用 下面就一步一步解释用法吧,以Linux为例讲解. 1, 首先确定你的python支持不支持ctypes python2.7以后cty ...
- C#集合中的Add与AddRange方法
C#.NET的集合主要位于System.Collections和System.Collections.Generic(泛型)这两个namespace中. 1.System.Collections 比如 ...
- 查看项目中的laravel的版本
方法1: 使用php artisan --version 方法2: 在项目文件中找vendor\laravel\framework\src\Illuminate\Foundation\Applicat ...