基于asio实现pop3的几个指令

来源:互联网 发布:圣马可吉他怎么样知乎 编辑:程序博客网 时间:2024/06/06 03:38
//测试#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 ();}}
注释不写了.睡觉去,再来就要实现一个邮件的解释器了,这个比较难


0 0
原创粉丝点击