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)接着把這些函數分别實作,然後,就可以實作郵件功能了
。