天天看點

簡單郵件傳輸協定(SMTP)

C語言代碼見: http://download.csdn.net/detail/huangminqiang201209/4841370  (這個代碼不太好,圖檔為附件有些問題,不過,現已經解決了

簡單郵件傳輸協定(SMTP)

一、電子郵件的組成

  在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傳回值表 

簡單郵件傳輸協定(SMTP)

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

簡單郵件傳輸協定(SMTP)

。