您的位置:首页 > 运维架构

基于asio实现pop3的几个指令

2015-04-06 01:40 134 查看
//测试

#include<iostream>
#include<pop3.h>

#include<fstream>
using namespace std;
using namespace email;

int main()
{
try{
io_service i;
pop3 p(i,"pop.126.com");
p.Set_DebugLevel (true);
p.Login ("******@126.com" , "*********");
cout << "noop:" << p.Noop () << endl;
cout << "noop:" << p.Stat () << endl;
cout << "dele:" << p.Dele (225) << endl;
cout << "rset:" << p.Rset () << endl;
cout << "list:" << p.List (225) << endl;

fstream retr("retr.txt" ,fstream::out);
fstream top("top.txt" ,fstream::out);

retr << p.Retr (225);
top << p.Top (225,20);

}
catch (std::exception e){
cout << e.what ();

}

}


头文件:

#ifndef POP3_H
#define POP3_H

#include<vector>
#include<iostream>
#include<sstream>
#include<boost/asio.hpp>
#include<boost/format.hpp>
#include<boost/algorithm/string.hpp>
#include<logging.h>
#include<MIME/base64.h>
namespace email {

#define CR "\r"
#define LF "\n"
#define CRLF "\r\n"

using namespace std;
using namespace boost;
using namespace boost::asio;
using namespace logging;
class pop3
{
public:
pop3(io_service& i,const string host, const string port = "pop3");
~pop3();
void Set_DebugLevel(bool value);
void Login(const string username, const string password);
string Quit();
int Stat();
size_t List(int which);
string Dele(int which);
string Noop();
string Rset();
string Retr(int which);
string Top(int which, int howmuch);

private:
string _Host;
string _Port;
bool _DebugLevel;

io_service& _Serivce;
ip::tcp::socket _Sock;
asio::streambuf _Streambuf;

void Create_Connection();
string Get_Line();
string Get_Response();
string Get_LongResponse();
void Put_Cmd(const string cmd, const string endline = CRLF);
string Short_Cmd(const string cmd);
string Long_Cmd(const string cmd);

};

}
#endif // POP3_H


实现

#include "pop3.h"

namespace email {

pop3::pop3(io_service& i, const string host, const string port)
: _Serivce(i),_Sock(i){

_Host = host;
_Port = port;
_DebugLevel = false;

Create_Connection ();
string wellcom = Get_Response ();

logger().info (wellcom);
}

pop3::~pop3 (){
/*
* 析构时发送quit命令
*/
Quit();
}

void pop3::Create_Connection(){
/*
* 迭代测试服务器
*/

ip::tcp::resolver Rsv(_Serivce);
ip::tcp::resolver::query query(_Host, _Port);

ip::tcp::resolver::iterator Iter;
ip::tcp::resolver::iterator EndIter;
boost::system::error_code err;
for(Iter = Rsv.resolve(query); Iter != EndIter; ++Iter){
_Sock.connect (*Iter,err);
if (!err)
break;
_Sock.close ();
}

if(err)
throw runtime_error("Create_Connection error");

logger().info ("Create_Connection succeed");
}

void pop3::Set_DebugLevel(bool value){
/*
* 设置调试级另
*/
_DebugLevel = value;
}

void pop3::Login(const string username, const string password){
/*
* 登陆,邮箱被锁住,直到发送Quit命令
*/
Short_Cmd ("User " + username);
Short_Cmd ("PASS " + password);

if (_DebugLevel)
logger().info ("login suceed");
}

string pop3::Quit(){
return Short_Cmd ("QUIT");
}

int pop3::Stat (){
/*
* STAT命令,返回邮件数量
* ingore是"+OK",忽略
*/
string resp = Short_Cmd ("STAT");

int how_many_emails;
string ingore;
stringstream sst(resp);
sst >> ingore >> how_many_emails;

return how_many_emails;
}

size_t pop3::List (int which){
/*
* 指定邮件的编号,返回该邮件字节数
* ingore是"+OK",忽略
*/
string resp = Short_Cmd (str(format("LIST %d") %which));

size_t size;
stringstream sst(resp);
string ingore;
sst >> ingore >> ingore >> size;

return size;
}

string pop3::Dele (int which){
/*
* 删除邮件
*/
return Short_Cmd (str(format("DELE %d") %which));
}

string pop3::Noop (){
/*
* 用于keep alive的指令
*/
return Short_Cmd("NOOP");
}

string pop3::Rset (){
/*
* quit之前,能恢复刚刚删掉的邮件
*/
return Short_Cmd("RSET");
}

string pop3::Top (int which, int howmuch){
/*
* which是邮件编号,howmuch是除掉头部之外,要返回的行数
*/
return Long_Cmd (str(format("TOP %d %d") %which %howmuch));
}

string pop3::Retr (int which){
/*
* 返回邮件内容
*/
return Long_Cmd (str(format("RETR %d") %which));
}

string pop3::Get_Line (){
/*
*从服务器读取一行,返回有可能以'\r','\n',或'\r\n'结尾
*/
size_t n = read_until(_Sock, _Streambuf, '\n');
std::istream is(&_Streambuf);
std::string line;
std::getline(is, line);

/*
* 把line开头可能的'\n'和结尾可能的'\r'删除
*/
if (boost::istarts_with(line, LF))
line.erase (line.begin ());
if (boost::iends_with(line, CR))
line.pop_back ();

return line;
}

string pop3::Get_Response(){
/*
* 服务器返回一行,如果以"+OK" 开始表示成功,否则失败抛出异常
*/
string line = Get_Line ();

if (_DebugLevel)
logger().debug ("*Get_Response*: " + line);

if (!boost::istarts_with(line, "+OK"))
throw std::exception("Get_Response error: -ERR");

return line;
}

string pop3::Get_LongResponse (){
/*
* 长指令,服务一共返回两次,第一次是"+OK. 1000字节"之类的提升信息,
* 第二次返回请求的内容,最后一行为"."
*/

auto log = Get_Response ();

if (_DebugLevel)
logger().info (log);

/*
* 第二次返回.每次读一行,前后的"\r\n已经被清除,直到收到:"."这一行表示完毕
*/
string lines;
string end(".");
for (string line = Get_Line (); line != end; line =Get_Line ()){
lines.append (line);
lines.append ("\n"); //在每一行重新加入换行符
}

return lines;
}

void pop3::Put_Cmd(const string cmd, const string endline){
/*
* 发送命令,行结束符endline默认是'\r\n'
*/
string line = cmd + endline;
size_t n = write(_Sock,buffer(line.data (),line.size ()));

assert(n == line.size ());

if (_DebugLevel)
logger().debug ("*Put_Cmd*: " + cmd);
}

string pop3::Short_Cmd(const string cmd){
/*
*发送命令,返回答应
*/
Put_Cmd (cmd);
return Get_Response ();
}

string pop3::Long_Cmd(const string cmd){
Put_Cmd (cmd);
return Get_LongResponse ();
}

}
注释不写了.睡觉去,再来就要实现一个邮件的解释器了,这个比较难
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: