C++实现含附件的邮件发送功能

C++实现邮件发送程序在vs2013测试通过,一共3个文件,发邮件的程序封装为Csmtp 类。

1.测试用的主函数

//
#include "Csmtp.h"
#pragma comment(lib, "Kernel32.lib") 

int main()
{ 

 Csmtp mail(
  25,
  "smtp.126.com",
  "username@126.com",// 来源邮箱
  "pwd",
  "username@126.com" //目标邮箱
  );

 if (!mail.CReateSocket())
 {
  cout << "ReateSocket failed!" << endl;
  return -1;//
 }
 mail.setTitle("test mail");
 mail.setContent("this is content.");

 mail.addfile("test1.png"); //添加附件
 mail.addfile("test2.png"); //添加附件

 mail.SendMail(); //类主函数

 return 0;
} 

2.Csmtp类定义

#include <iostream>
#include <string>
#include <vector>
#include <fstream> 

#include <WinSock2.h> //适用平台 Windows

#pragma comment(lib, "ws2_32.lib") /*链接ws2_32.lib动态链接库*/
 // POP3服务器(端口:110) Csmtp服务器(端口:25)
using namespace std;
class Csmtp
{ 

 int port;
 string domain;
 string user;
 string pass;
 string target;
 string title; //邮件标题
 string content; //邮件内容

 HOSTENT* pHostent;
 SOCKET sockClient; //客户端的套接字
 vector <string> filename; //存储附件名的向量

public: 

 Csmtp(
  int _port, //端口25
  string _domain,  //域名
  string _user,  //发送者的邮箱
  string _pass,  //密码
  string _target)  //目标邮箱
 :port(_port),domain(_domain),user(_user),pass(_pass), target(_target){};//内容
 bool CReateSocket();
 void setTitle(string tem){title = tem;}
 void setContent(string tem){content = tem;}

 int SendAttachment(SOCKET &sockClient);
 int SendMail();
 void addfile(string str){filename.push_back(str);}

}; 

3. Csmtp 类的实现

#include "Csmtp.h"
//#include <afx.h>//异常类
static const char base64Char[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char* base64Encode(char const* origSigned, unsigned origLength)
{
 unsigned char const* orig = (unsigned char const*)origSigned; // in case any input bytes have the MSB set
 if (orig == NULL) return NULL; 

 unsigned const numOrig24BitValues = origLength / 3;
 bool havePadding = origLength > numOrig24BitValues * 3;
 bool havePadding2 = origLength == numOrig24BitValues * 3 + 2;
 unsigned const numResultBytes = 4 * (numOrig24BitValues + havePadding);
 char* result = new char[numResultBytes + 3]; // allow for trailing '/0' 

 // Map each full group of 3 input bytes into 4 output base-64 characters:
 unsigned i;
 for (i = 0; i < numOrig24BitValues; ++i)
 {
  result[4 * i + 0] = base64Char[(orig[3 * i] >> 2) & 0x3F];
  result[4 * i + 1] = base64Char[(((orig[3 * i] & 0x3) << 4) | (orig[3 * i + 1] >> 4)) & 0x3F];
  result[4 * i + 2] = base64Char[((orig[3 * i + 1] << 2) | (orig[3 * i + 2] >> 6)) & 0x3F];
  result[4 * i + 3] = base64Char[orig[3 * i + 2] & 0x3F];
 } 

 // Now, take padding into account. (Note: i == numOrig24BitValues)
 if (havePadding)
 {
  result[4 * i + 0] = base64Char[(orig[3 * i] >> 2) & 0x3F];
  if (havePadding2)
  {
   result[4 * i + 1] = base64Char[(((orig[3 * i] & 0x3) << 4) | (orig[3 * i + 1] >> 4)) & 0x3F];
   result[4 * i + 2] = base64Char[(orig[3 * i + 1] << 2) & 0x3F];
  }
  else
  {
   result[4 * i + 1] = base64Char[((orig[3 * i] & 0x3) << 4) & 0x3F];
   result[4 * i + 2] = '=';
  }
  result[4 * i + 3] = '=';
 } 

 result[numResultBytes] = '\0';
 return result;
} 

int Csmtp::SendAttachment(SOCKET &sockClient) /*发送附件*/
{
 for (std::vector<string>::iterator iter = filename.begin();iter != filename.end(); iter++)
 {
  cout << "Attachment is sending··· " << endl; 

  string path=*iter;
  ifstream ifs(path, ios::in | ios::binary); //'或链接2个属性,以输入、二进制打开'
  if (false == ifs.is_open())
  {
   cout<<"无法打开文件!"<<endl;
   return 1;
  } 

  string sendstring;
  sendstring = "--@boundary@\r\nContent-Type: application/octet-stream; name=\"1.jpg\"\r\n";
  sendstring += "Content-Disposition: attachment; filename=\"1.jpg\"\r\n";
  sendstring += "Content-Transfer-Encoding: base64\r\n\r\n";
  send(sockClient, sendstring.c_str(), sendstring.length(), 0); 

  //infile.read((char*)buffer,sizeof(数据类型));

  // get length of file:
  ifs.seekg (0, ifs.end);
  int length = ifs.tellg();
  ifs.seekg (0, ifs.beg);
  cout<<"length:"<<length<<endl;
  // allocate memory:
  char * buffer = new char [length];
  // read data as a block:
  ifs.read (buffer,length);
  ifs.close();
  char *pbase;
  pbase = base64Encode(buffer, length);
  delete[]buffer;
  string str(pbase);
  delete[]pbase;
  str+="\r\n";
  int err =send(sockClient, str.c_str(), strlen(str.c_str()), 0); 

  if (err != strlen(str.c_str()))
  {
   cout << "文件传送出错!" << endl;
   return 1;
  }
 }
 return 0;
} 

bool Csmtp::CReateSocket()
{
 WSADATA wsaData;
 WORD wVersionRequested = MAKEWORD(2, 1);
 //WSAStarup,即WSA(Windows SocKNDs Asynchronous,Windows套接字异步)的启动命令
 int err = WSAStartup(wVersionRequested, &wsaData);
 cout<<"WSAStartup(0:successful):"<<err<<endl;

 char namebuf[128]; //获得本地计算机名
 string ip_list;
 if(0==gethostname(namebuf,128))
 {
  struct hostent* pHost; //获得本地IP地址
  pHost=gethostbyname(namebuf); //pHost返回的是指向主机的列表
  for (int i=0;pHost!=NULL&&pHost->h_addr_list[i]!=NULL;i++)
  {
   string tem = inet_ntoa(*(struct in_addr *)pHost->h_addr_list[i]);
   ip_list += tem;
   ip_list += "\n";
  }
 }
 else
 {
  cout<<"获取主机信息失败..."<<endl ;
 }
 //////////////////////////////////////////////////////////////////////////
 title=namebuf;// 邮件标题
 content=ip_list; //主机ip

 sockClient = socket(AF_INET, SOCK_STREAM, 0); //建立socket对象 

 pHostent = gethostbyname(domain.c_str()); //得到有关于域名的信息

 if (pHostent == NULL)
 {
  printf( "创建连接失败,也许没联网!\n" );
  return false;
 }

 return true;
}

int Csmtp::SendMail()
{
 char *ecode;

 char buff[500]; //recv函数返回的结果
 int err = 0;
 string message; //

 SOCKADDR_IN addrServer; //服务端地址
 addrServer.sin_addr.S_un.S_addr = *((DWORD *)pHostent->h_addr_list[0]); //得到smtp服务器的网络字节序的ip地址  

 addrServer.sin_family = AF_INET;
 addrServer.sin_port = htons(port); //连接端口25
 //int connect (SOCKET s , const struct sockaddr FAR *name , int namelen );
 err = connect(sockClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)); //向服务器发送请求
 cout<<"connect:"<<err<<endl;
 //telnet smtp.126.com 25 连接服务器结束
 buff[recv(sockClient, buff, 500, 0)]='\0';
 //cout<<"connect:"<<buff<<endl;

 message="ehlo 126.com\r\n";
 send(sockClient, message.c_str(), message.length(), 0); 

 buff[recv(sockClient, buff, 500, 0)]='\0';
 //cout<<"helo:"<<buff<<endl;

 message="auth login \r\n";
 send(sockClient, message.c_str(), message.length(), 0);
 buff[recv(sockClient, buff, 500, 0)]='\0';
 //cout<<"auth login:"<<buff<<endl;
 //上传邮箱名
 message=user;
 ecode = base64Encode(message.c_str(), strlen(message.c_str()));
 message = ecode;
 message += "\r\n";
 delete[]ecode;
 send(sockClient, message.c_str(), message.length(), 0);
 buff[recv(sockClient, buff, 500, 0)]='\0';
 //cout<<"usrname:"<<buff<<endl;
 //上传邮箱密码
 message=pass;
 ecode = base64Encode(message.c_str(), strlen(message.c_str()));
 message = ecode;
 delete[]ecode;
 message += "\r\n";
 send(sockClient, message.c_str(), message.length(), 0);
 buff[recv(sockClient, buff, 500, 0)]='\0';
 //cout<<"password:"<<buff<<endl;

 message="mail from:<"+user+">\r\nrcpt to:<"+target+">\r\n";
 send(sockClient, message.c_str(), message.length(), 0);
 buff[recv(sockClient, buff, 500, 0)]='\0';
 //cout<<"mail from: "<<buff<<endl;
 buff[recv(sockClient, buff, 500, 0)]='\0';
 //cout<<"rcpt to: "<<buff<<endl;

 message="data\r\n";//data要单独发送一次
 send(sockClient, message.c_str(), message.length(), 0);
 buff[recv(sockClient, buff, 500, 0)]='\0';
 //cout<<"data: "<<buff<<endl;
 ///-----------------------------------------DATA-------------------------------------
 //要使用Csmtp 发送附件, 需要对Csmtp 头信息进行说明, 改变Content-type 及为每一段正文添加BOUNDARY 名,
 cout<<"-------------------DATA------------------------"<<endl;
 // 头
 message="from:"+user+"\r\nto:"+target+"\r\nsubject:"+title+"\r\n";
 message += "MIME-Version: 1.0\r\n";
 message += "Content-Type: multipart/mixed;boundary=@boundary@\r\n\r\n";
 send(sockClient, message.c_str(), message.length(), 0); 

 // 正文
 message = "--@boundary@\r\nContent-Type: text/plain;charset=\"gb2312\"\r\n\r\n"+content+"\r\n\r\n";
 send(sockClient, message.c_str(), message.length(), 0); 

 //------------------------------------------------------------------------------------------------
 // 发送附件

 SendAttachment(sockClient);

 /*发送结尾信息*/
  message = "--@boundary@--\r\n.\r\n";
 send(sockClient, message.c_str(), message.length(), 0);
 buff[recv(sockClient, buff, 500, 0)]='\0';
 //cout<<"end_qwertyuiop:"<<buff<<endl;

 message="QUIT\r\n";
 send(sockClient, message.c_str(), message.length(), 0);
 buff[recv(sockClient, buff, 500, 0)]='\0';
 cout<<"Send mail is finish:"<<buff<<endl;
 return 0;
}

容易理解的简化版可以点击->这里

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C++实现发送邮件和附件功能

    本文实例为大家分享了C++实现发送邮件和附件的具体代码,供大家参考,具体内容如下 头文件 /************************* *发送邮件模块头文件 *可以发送文本和附件(支持多个附件一起发送) **************************/ #pragma once struct sMailInfo //邮件信息 { char* m_pcUserName;//用户登录邮箱的名称 char* m_pcUserPassWord;//用户登录邮箱的密码 char* m_pcS

  • C++发邮件简单实例详解

    C++发邮件用的是阻塞式socket模型,发送完数据后需要接收返回值,才能接着发送. 本程序不发送邮件附件,发附件的实例:C++实现含附件的邮件发送功能 #include <iostream> #include <string> #include <WinSock2.h> //适用平台 Windows using namespace std; #pragma comment(lib, "ws2_32.lib") /*链接ws2_32.lib动态链接库

  • C++实现邮件群发的方法

    本文实例讲述了C++实现邮件群发的方法.分享给大家供大家参考.具体如下: 关于生成随机QQ邮箱不精确的问题,在之后版本打算另写一个采集器插件进行帐号采集,所以,这个软件只用来进行内容发送,邮箱进行随机生成 如果你已经有采集来的QQ号,请复制到SendList.txt 替换内容即可 可以直接复制HTML代码到邮件内容,保存即可.目前邮件内容最大设置为10000字节,如果有增大的必要,欢迎提交留言. 这是我学习后VC编程中涉及到多线程,socket,及一些WINDOWS API的宗合应用 使用说明:

  • C++发送邮件实现代码

    本文实例为大家分享了C++发送邮件的具体代码,供大家参考,具体内容如下 首先,别忘了要设置发送邮箱的smtp,例如,假设你需要用网易邮箱,你需要去你的163邮箱设置开启smtp(有的邮箱还需要设置授权码).接着就可以用以下代码发送邮件了: // SendMail.h #ifndef _SEND_MAIL_H_ #define _SEND_MAIL_H_ #include <windows.h> #include <stdio.h> #include <WinSock.h>

  • C++实现含附件的邮件发送功能

    C++实现邮件发送程序在vs2013测试通过,一共3个文件,发邮件的程序封装为Csmtp 类. 1.测试用的主函数 // #include "Csmtp.h" #pragma comment(lib, "Kernel32.lib") int main() { Csmtp mail( 25, "smtp.126.com", "username@126.com",// 来源邮箱 "pwd", "use

  • Android实现带附件的邮件发送功能

    本文实例讲解了基于基于JMail实现Android邮件发送功能,分享给大家供大家参考,具体内容如下 在android上发送邮件方式: 第一种:借助GMail APP客户端,缺点是必须使用GMail帐号,有一点是比较方便,不需要写很多代码,但是不是很灵活. 第二种:基于JMail实现,可以很灵活的自己设置各种属性,不需要GMail帐号 在第二种方式的实现之前,看一下JMail对EMail结构的划分: 基于SMTP协议发送EMail,所以客户端必须要知道SMTP的主机. 腾讯邮件的SMTP主机为:s

  • Java实现带附件的邮件发送功能

    本文实例为大家分享了Java实现邮件发送功能的具体代码,供大家参考,具体内容如下 1.需要导入mail.jar.activation.jar这两个邮件发送的jar包,可在网上搜索并下载 2.需要设置相关邮箱服务器,我用的是QQ邮箱,操作如下所示:开启相关服务,并生产授权码(这个代码中会用到). 代码如下所示: package com.ecg.controller; import java.io.UnsupportedEncodingException; import java.security.

  • 利用Node.JS实现邮件发送功能

    第一步.配置篇 首先需要安装nodemailer库 npm install nodemailer//默认会安装最新的版本. 关于这个库的文档参见nodemailer 第二步.库的一些使用介绍 这个库使用方法很简单的.首先是要创建一个用于发送邮件的实例 var transporter = nodemailer.createTransport(transport[, defaults]) transport参数属性 属性太多了就只写一些关键的属性 port:连接的端口号,一般就是465 host:你

  • 深入Lumisoft.NET组件与.NET API实现邮件发送功能的对比分析

    我在另一篇文章<深入Lumisoft.NET实现邮件发送功能的方法详解>有大致对这个Lumisoft.NET组件的使用进行了介绍,当然Lumisoft.NET组件除了提供邮件发送功能外,还提供了邮件接收等功能的处理(包括基于POP3协议和IMAP协议),而.NET则除了提供SMTP协议功能外,则没有提供POP3协议处理的相关类库,因此收取邮件这需要自己进行封装(需要也可以参考codeproject.com上的相关文章). 1..NET的邮件发送功能实现.NET本身封装了一个SmtpClient

  • python实现SMTP邮件发送功能

    一直想着给框架添加邮件发送功能.所以整理下python下邮件发送功能 首先python是支持邮件的发送.内置smtp库.支持发送纯文本.HTML及添加附件的邮件.之后是邮箱.像163.qq.新浪等邮箱默认关闭SMTP服务,需要我们手动打开,打开后通过发件人邮箱.授权密码 通过发件人的SMTP服务发送 代码如下: #!/usr/bin/env python # -*- coding: utf_8 -*- from email.mime.text import MIMEText from email

  • 深入Lumisoft.NET实现邮件发送功能的方法详解

    在前面的一些文章中,有介绍过DotNet内置SMTP类的邮件发送功能,附件.嵌入图片的模式都有介绍,本文继续介绍Lumisoft.NET这个非常优秀的开源组件,用该组件来设计开发邮件工具,将变得更加方便,功能更加强大.网上很多文章基本介绍如何使用该组件来收取邮件较多,较少介绍使用该组件做邮件发送功能的.本文主要探寻使用该组件实现邮件的发送功能,邮件发送有两种方式,一种是不用发件人即可发送邮件,一种是使用发件人账户密码和SMTP服务器来实现邮件发送的,本文分别对这两种方式进行介绍. 组件下载地址:

  • 使用Spring的JAVA Mail支持简化邮件发送功能

    闲来无事,翻看<Spring in Action>,发现Spring集成了对JAVA Mail的支持,有点小激动的看了一遍,嗯,话说真的简单了很多. Spring的邮件发送的核心是MailSender接口,在Spring3.0中提供了一个实现类JavaMailSenderImpl,这个类是发送邮件的核心类.可以通过在配置文件中配置使用,当然也可以自己硬编码到代码中(方便起见,下面的演示代码都是硬编码到代码中,省得配置麻烦). Spring提供的邮件发送不仅支持简单邮件的发送.添加附件,而且还可

  • JavaWeb实现邮件发送功能

    基于JavaWeb的邮件发送功能(多附件),供大家参考,具体内容如下 本次学习主要目的是为了测试由QQ邮箱发送到任意一个有效邮箱的功能实现,附带多个附件.学习者可以借鉴其他邮箱的格式,梳理一下要写的内容.项目把文件内容放到了MimeMessage 邮件对象里,其中包含了如发件人.收件人.抄送人.邮件主题.邮件内容.邮件时间和邮件附件等一些内容. 项目中遇到的问题: 1.在执行到 File file = new File("D:\Chat_Software\sky.JPG");时出现错误

  • SpringBoot实现邮件发送功能的姿势分享

    目录 前言 I. 项目环境 1. 项目依赖 2. 配置 II. 邮件发送 1. 简单文本邮件发送 2. html发送 3. 添加附件 4. Freemaker模板 5. 测试与小结 III. 不能错过的源码和相关知识点 0. 项目 总结 前言 邮件发送,在实际的项目开发中,可能用的不是特别多,如果没有特定的需求,相信也没有多少小伙伴会特意的去关注,那么如果现在我们希望针对项目做一个异常的报警系统,当出现异常的时候,可以向指定的小伙伴发送邮件提醒,那么让我们来实现这个功能,可以怎么办呢? 这里介绍

随机推荐