C语言代码见: http://download.csdn.net/detail/huangminqiang201209/4841370 (这个代码不太好,图片为附件有些问题,不过,现已经解决了)
一、电子邮件的组成
在SMTP协议中,电子邮件由三部分组成,信封、首部和正文。
1) 信封
信封包括发信人的邮件地址和接收人的邮件地址,用两条SMTP 命令指明。
① MAIL FROM:<发信人的地址>,告诉SMTP服务器发信人的地址。
② RCPT TO:<收信人的地址>,告诉SMTP服务器收信人地址。
2)首部
首部中常用命令:
① FROM :< 姓名>< 邮件地址> ,表明邮件发送者是谁。
② TO :< 姓名>< 邮件地址> ,表明邮件接收者是谁。
③ SUBJECT :< 邮件标题> ,表明邮件的主题。
④ DATE :< 时间> ,表明发邮件的时间。
⑤ REPLY-TO :< 邮件地址> ,表明邮件的回复地址。
⑥ Content-Type :< 邮件类型> ,表明邮件包含文本、HTML 超文本和附件的哪些类型。
⑦ X-Priority :< 邮件优先级> ,表明邮件的发送优先级。
⑧ MIME-Version :< 版本> ,MIME 的意思是Multipurpose Internet Mail Extensions ,即多用途Internet 邮件扩展标准,它对传输内容的消息、附件及其他的内容定义了格式。
3)正文
正文是邮件的内容。首部以一个空行结束,再下面就是正文部分。
4) 结束符号
邮件以“.” 结束。
二、与邮件服务器连接
1.与SMTP服务器的连接
使用命令格式:HELO<信息发送端的名称>
格式举例:HELO Local
2.与ESMTP服务器建立连接
(1) 使用命令格式:EHLO<信息发送端的名称>
格式举例:EHLO Local
(2) 启动服务器认证
命令格式:AUTH LOGIN
3.断开与服务器的连接
命令格式:QUIT
使用QUIT命令退出系统,断开与服务器的连接。
三、邮件的发送过程
以与ESMTP服务器建立连接发送邮件为例。
1.客户端先与服务器建立连接
1) 客户端发送EHLO Local
2) 客户端发送AUTH LOGIN
3) 客户端发送经过Base64编码处理的用户名
4) 客户端发送经过Base64编码处理的密码
2.客户端开始发送邮件的信封
5) 客户端发送 MAIL FROM:<发信人的地址>
6) 客户端发送 RCPT TO:<收信人的地址>
3.客户端开始发送邮件数据
7) 客户端发送DATA
8) 客户端可以选择发送邮件的首部字段
9) 客户端发送一个空行表示邮件首部结束。
10) 客户端开始发送正文。
11) 客户端发送“.”表示邮件发送结束。
4.客户端先服务器断开连接
12) 客户端发送QUIT表示断开连接。
四、SMTP Server返回值表
五、C++语言实现(头文件)
/**************************************************************************************************************
**文件:Email.h
**编写者:huangminqiang
**编写日期:2012年12月12号
**简要描述:邮件发送头文件
**修改者:
**修改日期:
**注:注意extern "C" 和__cplusplus的用法
**************************************************************************************************************/
#ifndef __Email_H__
#define __Email_H__
typedef struct Email_info{
char* smtp_server;
char* username;
char* password;
char* sender_name;
char* sender_Email;
char* recv_Email;
char* subject;
char* textinfo;
char* attachment[10];
}Email_info_t;
#ifdef __cplusplus
#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
using namespace std;
#ifdef __cplusplus
extern "C" {
#endif //__cplusplus
#define _DEBUG(msg...) printf("[ %s,%s, %d ]=>",__FILE__, __FUNCTION__, __LINE__); printf(msg); printf("\r\n")
#define _ERROR(msg...) printf("[ error: %s, %d]=>", __FILE__, __LINE__); printf(msg); printf("\r\n")
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1
#define BUFFER_SIZE (10*1024) // 收发数据的大小:1M
#define BUFFER_CNT 5 // 附件中最大数据包的个数,附件不能超过5M = (BUFFER_SIZE) * (BUFFER_CNT)
typedef int SOCKET;
class Email
{
public:
Email();
~Email();
void AddAttachment(const char* path);
void AddTextMsg(const char* Text);
void Send();
void SetSubject(const char* );
void SetSenderName(const char* );
void SetSenderEmail(const char* );
void SetRecvEmail(const char* );
void SetUsername(const char* );
void SetPassword(const char* );
void SetSMTPServer(const char* server,const unsigned short port=0);
bool is_send;
private:
string SMTPSrvName;
unsigned short SMTPSrvPort;
string Username;
string Password;
string EmailFrom;
string EmailTo;
string NameFrom;
string TextMsg;
string Subject;
SOCKET hSocket;
char* SendBuf;
char* RecvBuf;
vector<std::string> Attachments;
void ReceiveData();
void SendData();
int FormatHeader(char* );
int SmtpRecdigits();
SOCKET ConnectRemoteServer(const char* serverIP, const unsigned short port=0);
string base64_encode(unsigned char const*, unsigned int len);
};
int Email_send(Email_info_t );
#ifdef __cplusplus
}
#endif //__cplusplus
#endif //__cplusplus
#endif // __Email_H__
因为邮件发送只是一个模块而已,项目中涉及到C\C++混合编程问题,所以,强调了extern "C"和__cplusplus的作用。Email_info_t这个结构体的用途为提供对外的传参信息,通过int Email_send(Email_info_t )函数----C++对外的接口函数,C文档(*.c)中只需调用这个接口就ok了,而C++(*.cpp)接着把这些函数分别实现,然后,就可以实现邮件功能了。