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;
}
};