IMAP协议程序设计入门(VC篇)

来源:互联网 发布:千牛工作台mac版怎么用 编辑:程序博客网 时间:2024/06/10 14:24

IMAP协议程序设计入门(VC篇)


最近在搞邮件接收的程序,网络上找到很多pop3的例子代码,很遗憾,我认识的所有邮箱都不再支持pop3,无奈只能用imap。Imap编程的资料相当匮乏,以至于没有找到一个示例程序,通过抓包和学习协议,终于把整个流程跑通了。不多废话,直接上一个简单而且相对完整的基本流程。

1. 登录
指令:LOGIN user password
C语言字符串示例:"C1 LOGIN user@163.com \"password\"\r\n"
要点:a.密码必须被双引号(“”)包起来;b.结尾必须加回车换行(\r\n),其他指令一样;c.命令开头的C1只是个标记,便于同服务器的应答对应,换成任意字符串都没关系,其他指令一样。

2. 选文件夹
指令:SELECT folder
C语言字符串示例:"C2 SELECT \"INBOX\"\r\n"
要点:文件夹名称要被双引号包起来。

3. 获取邮件
指令:FETCH
C语言字符串示例:"C3 fetch 1:1 body[header.fields (subject)]\r\n"
要点:fetch指令功能强大、比较复杂不能列举,示例获取第一个邮件信头中的邮件主题。

4. 退出
指令:LOGOUT
C语言字符串示例:"C4 LOGOUT\r\n"
要点:没有参数。

以上只是一个很简单、基础的流程,需要进一步学习可以参考IMAP协议,不想看原始文档的话,网上有个叫做《IMAP命令学习》的文章貌似还可以,但是学习指令距离编码还是有很大的距离。关于编码可以通过foxmail+网络抓包工具分析发送的数据包,确定代码的流程和数据收发规范。

以下是上述例子的完整VC代码,vs2008编译通过,仅供流程演示,收发流程、错误处理等未细致处理。

 

#include "stdafx.h"#include "stdio.h" #include "winsock2.h"   #pragmacomment(lib,"ws2_32.lib")   int _tmain(int argc, _TCHAR* argv[]){SOCKADDR_INsaServer;LPHOSTENTlphostent;WSADATAwsadata;SOCKEThSocket;intnRet;char*   host_name="imap.163.com";// 初始化套接字if(WSAStartup(MAKEWORD(2,2),&wsadata))   {printf("初始化SOCKET出错!\n");return 0;}// imap端口默认是143lphostent=gethostbyname(host_name);   if(lphostent==NULL) {printf("lphostent为空!\n");return 0;}hSocket   =   socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);   saServer.sin_family = AF_INET;   saServer.sin_port = htons(143);   saServer.sin_addr = *((LPIN_ADDR)*lphostent->h_addr_list);// 连接imap服务器nRet = connect(hSocket,(LPSOCKADDR)&saServer,sizeof(SOCKADDR_IN));   if(nRet == SOCKET_ERROR)   {   printf("建立连接出错!\n");   closesocket(hSocket);   return 0;   }// 登陆邮箱char*   req= "C1 LOGIN user@163.com \"password\"\r\n";nRet = send(hSocket, req, strlen(req), 0);// 选择文件夹(“收件箱”)char*   req2 = "C2 SELECT \"INBOX\"\r\n";nRet = send(hSocket, req2, strlen(req2), 0);// 获取信头中邮件主题字段char* req3 = "C3 fetch 1:1 body[header.fields (subject)]\r\n";nRet = send(hSocket, req3, strlen(req3), 0);// 退出登陆char* req4 = "C4 LOGOUT\r\n";nRet = send(hSocket, req4, strlen(req4), 0);// 设置接收bufferchar*  pRecvBuf = new char[10*1024]; //10KBytememset(pRecvBuf, 0, 10*1024);// 接收返回数据包do{nRet = recv(hSocket, pRecvBuf, 10*1024, 0);   if(nRet > 0)   pRecvBuf[nRet] = 0;   else   break;printf("----server return:----\n%s", pRecvBuf);   }while(nRet);delete[] pRecvBuf;closesocket(hSocket);return 0;}


以下是服务器返回的数据:

----server return:----* OK Coremail System IMap Server Ready(163com[e1bcd9800c6738c0b489cc004e7a0443])----server return:----C1 OK LOGIN completed----server return:----* 1 EXISTS* 0 RECENT* OK [UIDVALIDITY 1] UIDs valid* FLAGS (\Answered \Seen \Deleted \Draft \Flagged)* OK [PERMANENTFLAGS (\Answered \Seen \Deleted \Draft \Flagged)] LimitedC2 OK [READ-WRITE] SELECT completed----server return:----* 1 FETCH (BODY[HEADER.FIELDS (SUBJECT)] {44}Subject: A E-Mail is Received from imap!)C3 OK Fetch completed----server return:----* BYE IMAP4rev1 Server logging outC4 OK LOGOUT completed


 

原创粉丝点击