C++ 建立郵件客戶端之收郵件(利用POP3)(一)

POP是郵局協議(Post Office Protocol),使TCP/IP協議族中的一員,它是由RFC 1939定義的.

本協議主要是用於支持使用客戶端遠程管理在服務器上的電子郵件.最新版本是POP3,全名是"Post Office Protocol - version 3".

一.POP的命令:

1.user username ------向服務器發送用戶名;

2.pass password ------向服務器發送密碼;

3.apop name,digest -------一種安全傳輸口令的辦法,digest是md5消息摘要;

4.stat  ----------請求服務器發回關於郵箱的統計資料,比如郵件總數和總字節數;

5.uidl [msg#] -----------返回郵件的唯一標識符;

6.list   -----------返回郵件數量和每個郵件的大小;

7.retr [msg#] ---------返回由參數標識的郵件的全部文本;

8.dele [msg#] ---------服務器將由參數標識的郵件標記爲刪除,由quit命令執行;

9.rset  ---------服務器將重置所有標記爲刪除的郵件,用於撤銷dele命令;

10.top [msg#],[n] -----服務器將返回由參數標識的郵件的前n行內容,n必須是正整數;

11.noop ----------服務器返回一個肯定的相應,不作任何操作;

12.quit ---------更新,退出;

二.建立POP3客戶機流程:

建立SOCKET----->連接到指定服務器(如:pop.126.com)------->服務器會返回"+ok"--------->發送用戶名和密碼--------->服務器會返回響應-------->發送命令------>返回命令響應------>執行quit命令退出------->關閉SOCKET

三.部分代碼實現:

//類:

class SocketRM
{
public:
	SocketRM();
	~SocketRM();
	void getHostAddr();
	void ConnectServer();
	void loginServer();
	void SayHELLO();
	void SayAUTH();
	void GetList();
	void GetUIDL();
	void GetEmailInfo();
	void GetFromInfo();
	void GetSubjectInfo();
	void GetDATE();
private:
	SOCKET ServMail;
	SOCKADDR_IN ServAddr;
	WSADATA wsd;
	hostent *ptr;			//通過地址獲取完整的服務器地址
	in_addr addr;			//將地址轉成以.相隔的IP地址,然後通過inet_addr函數轉爲unsigned long型
	char buf[2048];			//接收登錄信息從Server傳回來的數據
	char recvbuf[20000];		//從SOCKET緩存區複製的本地緩存變量
	std::string User;		//用戶名....POP協議登錄信息;
	std::string Psd;		//密碼
	std::string FromStr;		//解碼輸入字符串
	std::string OutStr;		//解碼輸出字符串
	std::string bufStr;		//緩存所下載的郵件信息
	std::string Order;		//POP命令
};

//將pop.126.com轉換爲IP地址;

void SocketRM::getHostAddr()
{
	//ptr是一個hostent類型的指針,目的就是通過gethostbyhome()函數獲取目標
	//爲pop.126.com的hostent的結構指針。
	ptr=gethostbyname("pop.126.com");
	if(ptr==nullptr)
		std::cout<<"GetHostByName Error..."<<std::endl;
	//pop.126.com是一個不可用的地址,要將它轉換成unsigned long形的變量
	//傳遞到servAddr.sin_Addr.s_addr中。
	memcpy(&addr,ptr->h_addr_list[0],sizeof(in_addr));
	
};

//建立SOCKET

void SocketRM::ConnectServer()
{
	if((ServMail=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR)
	{
		std::cout<<"ServMail ERROR..."<<std::endl;
		WSACleanup();
		closesocket(ServMail);
	}

	getHostAddr();

	ServAddr.sin_family=AF_INET;
	ServAddr.sin_port=htons(110);
	ServAddr.sin_addr.s_addr=inet_addr(inet_ntoa(addr));

	int len=sizeof(SOCKADDR_IN);
	int ret;
	
	if((ret=connect(ServMail,(LPSOCKADDR)&ServAddr,len))==INVALID_SOCKET)
	{
		std::cout<<"Connect Error..."<<std::endl;
		closesocket(ServMail);
		WSACleanup();
	}
	else
	{
		ZeroMemory(buf,2048);
		recv(ServMail,buf,2048,0);
		std::cout<<"Connect Success..."<<std::endl;
		std::cout<<"Server:"<<buf<<std::endl;

	}
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章