⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smailer.cpp

📁 关于smtp的网络编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				start=0;
				return  _content;
			}		
			
			if(start==1)
			{
			//	_content+=strfile.substr(0,j)+"\r\n";	
                temp=strfile.substr(0,SENDCOUNT);
				_content+=MUtils::Base64Helper::encode(temp)+"\r\n";
			}		
			else
			{

			//	_content+=strfile.substr((start-1)*j,j)+"\r\n";
				temp=strfile.substr((start-1)*SENDCOUNT,SENDCOUNT);
				_content+=MUtils::Base64Helper::encode(temp)+"\r\n";
			}							
	
	}
	else
	{		
		//分界线 标示为一组
		_content  = "--" + _boundary + "\r\n";
		
		_content += "Content-Type: ";
		_content += (*_con_itr)->getType() + "\r\n";
		
		//得到当前文件
		std::string disposition = (*_con_itr)->getDisposition();
		if ( !disposition.empty() )
		{
			_content += "Content-Disposition: ";;
			_content += disposition + "\r\n";
		}
		
		_content += "Content-Transfer-Encoding: ";
		_content += (*_con_itr)->getTransEncoding() + "\r\n\r\n";
		
		_content += (*_con_itr)->getContent() + "\r\n\r\n";


		//"application/octet-stream;
		_con_itr++;
	}
    return _content;
}

//得到未尾
std::string MailWrapper::getEnd()
{
    std::string end;

    end += "\r\n--" + _boundary + "--\r\n";

    end += ".\r\n";

    return end;
}

//准备from 
std::string MailWrapper::prepareFrom()
{
    std::string from_string;

    from_string = prepareName(_mail_info->getSenderName());
    from_string += getSenderAddress();

    return from_string;
}

//准备to
std::string MailWrapper::prepareTo()
{
    std::string to_string;

    traverseReceiver();
    while ( hasMoreReceiver() )
    {
        to_string += prepareName(_rcv_itr->first);
        to_string += nextReceiverAddress() + ", ";
    }

    return to_string.substr(0, to_string.length()-2);
}

//准备日期
std::string MailWrapper::prepareDate()
{
    char date_string[MAX_BUFFER_SIZE];

    time_t seconds;
    time(&seconds);
    strftime(date_string, MAX_BUFFER_SIZE, 
             "%a, %d %b %y %H:%M:%S +0800", 
             localtime(&seconds));          // +0800 maybe hard code

    return date_string;
}

//准备标名
std::string MailWrapper::prepareName(const std::string raw_name)
{
    std::string decorated_name;

    if (!raw_name.empty())
    {
        decorated_name  = "\"";
        decorated_name += raw_name;
        decorated_name += "\" ";
    }

    return decorated_name;
}

// Member functions of class MailSender
/////////////////////////////////////
//邮件发送者
MailSender::MailSender(const std::string server_name, 
                       const std::string user_name, 
                       const std::string user_pwd)
    : _server_name(server_name), _user_name(user_name), 
      _user_pwd(user_pwd), _mail(0)
{
    conn();

	 hello();
    if ( !user_name.empty() )
        login();

   
}

MailSender::~MailSender()
{
    quit();
}

//设置邮件封装对象
void MailSender::setMail(MailWrapper* mail)
{
    _mail = mail;
}

//发送邮件
void MailSender::sendMail()
{
    if (!_mail)
        return;

    sendHeader();
    sendContent();
    sendEnd();
}

void MailSender::conn()
{
    struct hostent* host = gethostbyname(_server_name.c_str());
    if (host == 0)
    {
        throw MailException("Get server infomation error");
    }

    _socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//IPPROTO_TCP

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = *(ULONG *)host->h_addr_list[0];
    server_addr.sin_port = htons(SERVICE_PORT);

    connect(_socket, (struct sockaddr *)&server_addr, sizeof(server_addr));
    rcvResponse("220");



	int TimeOut=6000*10*60; //设置发送超时6秒
    if(::setsockopt(_socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){
       return ;

	   //设置非阻塞方式连接
    unsigned long ul = 1;
    if(ioctlsocket(_socket, FIONBIO, (unsigned long*)&ul)==SOCKET_ERROR);
      return ; 


    //setsockopt(socket, IPPROTO_TCP, TCP_MAXSEG, VOID*, size_t)

//     setsockopt(_socket,IPPROTO_TCP,TCP_MAXSEG,VOID*,(socklen_t)1024*1024*2);
	 //setsockopt(sock, SOL_SOCKET, SO_RCVBUF/SO_SNDBUF, &bufsize, (socklen_t)len)
}


}

//发送通知命令
void MailSender::hello()
{
    char local_host[MAX_BUFFER_SIZE];
    if ( gethostname(local_host, MAX_BUFFER_SIZE) != 0 )
    {
        throw MailException("Get local host name error");
    }

    std::string msg;

    msg  = "HELO ";
    msg += std::string(local_host) + "\r\n";
    sendRequest(send_helo_cmd, msg);
    rcvResponse("250");
}

//发送登录命令
void MailSender::login()
{
    std::string msg;

    msg = "AUTH LOGIN\r\n";
    sendRequest(send_auth_cmd, msg);
    rcvResponse("334");

    msg = MUtils::Base64Helper::encode(_user_name) + "\r\n";
    sendRequest(send_username, msg);
    rcvResponse("334");

    msg = MUtils::Base64Helper::encode(_user_pwd) + "\r\n";
    sendRequest(send_password, msg);
    rcvResponse("235");
}

//发送标题
void MailSender::sendHeader()
{
    std::string msg;

    msg  = "MAIL FROM: ";
    msg += _mail->getSenderAddress() + "\r\n";
    sendRequest(send_mail_cmd, msg);
    rcvResponse("250");

    _mail->traverseReceiver();
    while ( _mail->hasMoreReceiver() )
    {
        msg  = "RCPT TO: ";
        msg += _mail->nextReceiverAddress() + "\r\n";
        sendRequest(send_rcpt_cmd, msg);
        rcvResponse("250");
    }

    msg  = "DATA\r\n";
    sendRequest(send_data_cmd, msg);
    rcvResponse("354");

    sendRequest(send_header, _mail->getHeader());
}

//发送正文
void MailSender::sendContent()
{
    _mail->traverseContent();
    while ( _mail->hasMoreContent() )
    {
		
        sendRequest(send_content, _mail->nextContent());

    }
}

//发送结束
void MailSender::sendEnd()
{
    sendRequest(send_end, _mail->getEnd());
    rcvResponse("250");
}

//发送退出
void MailSender::quit()
{
    sendRequest(send_quit_cmd, "QUIT\r\n");
    rcvResponse("221");

    closesocket(_socket);
}

//接收到返回信息
void MailSender::rcvResponse(const std::string expected_response)
{
    int recv_bytes = 0;
    char response_buffer[MAX_BUFFER_SIZE];
    if ( (recv_bytes = recv(_socket, response_buffer, MAX_BUFFER_SIZE, 0)) < 0 )
    {
        throw MailException( 
            ErrorMessage::getInstance().response(expected_response)
        );
    }

    std::string response(response_buffer, recv_bytes);
    std::cout << "[INFO]RECV(" << expected_response << "):" 
              << response << std::endl;
    if ( response.substr(0, 3) != expected_response )
    {
        throw MailException( 
            ErrorMessage::getInstance().response(expected_response)
        );
    }
}

//发送请求
void MailSender::sendRequest(Operaion operation, 
                             const std::string content)
{
    std::cout << "[INFO]SEND:" << content << std::endl;

    if ( send(_socket, content.c_str(), content.length(), 0) < 0 )
    {
        throw MailException(
            ErrorMessage::getInstance().request(operation)
        );
    }
}

// Member functions of class ErrorMessage
/////////////////////////////////////

ErrorMessage& ErrorMessage::getInstance()
{
    static ErrorMessage _instance;
    return _instance;
}

ErrorMessage::ErrorMessage()
{
    _request_errmsg_map[MailSender::send_helo_cmd] = "Send HELO cmd error";
    _request_errmsg_map[MailSender::send_auth_cmd] = "Send AUTH cmd error";
    _request_errmsg_map[MailSender::send_username] = "Send user name error";
    _request_errmsg_map[MailSender::send_password] = "Send user password error";
    _request_errmsg_map[MailSender::send_mail_cmd] = "Send MAIL FROM cmd error";
    _request_errmsg_map[MailSender::send_rcpt_cmd] = "Send RCPT TO cmd error";
    _request_errmsg_map[MailSender::send_data_cmd] = "Send DATA cmd error";
    _request_errmsg_map[MailSender::send_header  ] = "Send mail header error";
    _request_errmsg_map[MailSender::send_content ] = "Send mail content error";
    _request_errmsg_map[MailSender::send_end     ] = "Send mail end error";
    _request_errmsg_map[MailSender::send_quit_cmd] = "Send QUIT cmd error";

    _respons_errmsg_map["220"] = "Server connect error";
    _respons_errmsg_map["250"] = "General server error";
    _respons_errmsg_map["334"] = "Server authentication error";
    _respons_errmsg_map["235"] = "Password error";
    _respons_errmsg_map["354"] = "Server not ready for data";
    _respons_errmsg_map["221"] = "Server didn't terminate session";
}

//错误请求
std::string& ErrorMessage::request(MailSender::Operaion request_operation)
{
    return _request_errmsg_map[request_operation];
}

//错误返回
std::string& ErrorMessage::response(const std::string expected_response)
{
    return _respons_errmsg_map[expected_response];
}

} // namespace SMailer

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -