O3客户端教学实验_第1页
O3客户端教学实验_第2页
O3客户端教学实验_第3页
O3客户端教学实验_第4页
O3客户端教学实验_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、实验目的操作系统,windows xp home edition版本Vc+ 6.0编译器接入互联网实验目的理解POP3协议原理,对邮件接收信息内容进行分析,熟悉SOCKET编程,来实现POP3客户端。实验内容实现一个简单的POP3客户端。连接POP3服务器.实现命令:USER,PASS,STAT,LIST,RETR,DELE,QUIT。3接收邮箱所有邮件4邮件进行分析,解析出:主题,发件人,发件时间,发件内容。5对个部分内容进行传输编码的解码,根据传输编码,进行base64解码或Quoted-Printable的解码6进行编码转换,将邮件原编码UTF8,GBK或7bit等转换为GBK,可以正确

2、在本机上显示程序运行在实验的时候,对和进行了测试,以下是对服务器,用户pop3client,密码123456的演示(通过选取下拉框中的主题切换邮件)登录界面:显示界面:点击删除按钮:程序实现程序结构base64_dequoted.h :存放对base64和quoted的解码函数1int DecodeQuoted(const char* pSrc, unsigned char* pDst, int nSrcLen)/对quoted传输编码进行解码2void Decode(const char *szCoded, BYTE *pOut) /对base64传输编码进行解码StructInfo.h:

3、根据邮件的格式,设计的一个结构体struct MailInfoCString m_Subject;/邮件的主题CString s_Time; /邮件发送时间CString s_Person; /邮件的发送人CString m_Contex; /邮件的内容CString m_Code; /邮件的编码;PopClient.cpp: 存放对pop3的命令操作:USER,PASS,STAT,LIST,RETR,DELE,QUITbool ConToServer(const char* sName)/连接pop3服务器,sName为pop3服务器名字或者ip;bool LoginToServer(con

4、st char *uName,const char *uPass)/登陆POP3服务器,用户名为uName,用户密码为uName;bool RecvFromServer(vector &m_Info) /从POP3服务器获取邮件信息,将信息存储在容器m_Info中;bool DeleteFromServer(int index) /从POP3服务器删除某个邮件,index指定删除邮件的标示号bool QuitFromServer() /从pop3服务器退出int RecvData(void *pData, int nLen) /接收nLen长度的流,在接收大数据量邮件的时候,需要循环读取流vo

5、id StringToStruct(const char * msgBuf,MailInfo &mailInfo) /将获取的邮件字符串流,转换到对应的结构体mailInfo中,便于以后显示和操作int GetContent(char *destStr,CString &dStr,CString code) /获取邮件正文进行传输编码解码,并将编码转换为GBK,存储在dStr中,code为正文的编码int GetGBKSubject(char *destStr,CString &dStr) /将destStr进行qp或base64解码后,转换为GBK,存储于dStr中int GetAdress

6、(char *destStr,CString &dStr) /找出邮箱的地址,为之间的内容,或者直接为“From:”后面的值,存储于dStr中LoginDlg.cpp: 用于登录对话框,接收用户输入的pop3服务器地址,用户名和密码,调用PopClient.cpp中的函数连接服务器,登录服务器PClientDlg.cpp:用于显示邮件的主题,时间,发件人,内容等信息的对话框,还可以进行删除操作和退出操作。连接服务器采用流方式tcp创建socket,可以根据服务器名(如)或者服务器IP(如sina的pop3的ip: 42),服务器端口号110; 服务器返回+OK 表示成功;/*采用tcp传输*/

7、 pClient = socket(AF_INET,SOCK_STREAM,0); /*设置POP3服务器的IP以及地址信息*/SOCKADDR_IN pServerAddr; /存储pop3服务器的地址和端口pServerAddr.sin_family = AF_INET; pServerAddr.sin_port = htons(110); /服务器端口为110pServerAddr.sin_addr.s_addr = inet_addr(sName);if (pServerAddr.sin_addr.s_addr = INADDR_NONE)HOSTENT *hostInfo; /存储服

8、务器地址信息hostInfo = gethostbyname(sName); pServerAddr.sin_addr.s_addr = *(unsigned long *)hostInfo-h_addr); /服务器IP地址int ret; /记录函数执行返回值/*连接POP3服务器*/ret = connect(pClient,(SOCKADDR *)&pServerAddr,sizeof(SOCKADDR);if (ret = SOCKET_ERROR)return false;char msgBuf501; /存储服务器返回信息int msgLen; /存储服务器返回信息长度msgLe

9、n = recv(pClient,msgBuf,500,0);if (msgLen = SOCKET_ERROR | msgLen = 0)return false;msgBufmsgLen = 0;if (strncmp(msgBuf,+OK,3) != 0) /服务器返回非+OK表示连接失败return false;return true;登录服务器根据用户输入的用户名和密码,分别向服务器发送USER xxxrn, PASS xxxrn,服务器返回+OK 表示成功char msgBuf501; /用于存储发送和接受字符串int ret; /记录函数执行返回值int msgLen; /发送或

10、接受字符串长度/发送用户名给服务器msgBuf0 = 0;strcat(msgBuf,USER );strcat(msgBuf,uName);strcat(msgBuf,rn);ret = send(pClient,msgBuf,strlen(msgBuf),0);if (ret = SOCKET_ERROR | ret = 0)return false;/接收服务器返回信息msgLen = recv(pClient,msgBuf,500,0);if (msgLen = SOCKET_ERROR | msgLen = 0)return false;msgBufmsgLen = 0;if (st

11、rncmp(msgBuf,+OK,3) != 0) /服务器返回非+OK表示用户名发送成功return false;/发送用户密码给服务器msgBuf0 = 0;strcat(msgBuf,PASS );strcat(msgBuf,uPass);strcat(msgBuf,rn);ret = send(pClient,msgBuf,strlen(msgBuf),0);if (ret = SOCKET_ERROR | ret = 0)return false;/接收服务器返回信息msgLen = recv(pClient,msgBuf,500,0);if (msgLen = SOCKET_ERR

12、OR | msgLen = 0)return false;msgBufmsgLen = 0;if (strncmp(msgBuf,+OK,3) != 0) /服务器返回非+OK表示用户登录失败return false;return true;接收邮件首先向服务器发送STAT命令,获取邮件的个数mCount,然后根据mCount的个数循环从pop3服务器获取邮件;首先用LIST x命令获取x邮件的大小,然后根据大小接收此邮件,并将其存储于mailInfo结构体char msgBuf501; /用于存储发送和接受字符串int ret; /记录函数执行返回值int msgLen; /发送或接受字符串

13、长度m_Info.clear();/向服务器发送请求邮箱信息strcpy(msgBuf,STATrn);ret = send(pClient,msgBuf,strlen(msgBuf),0);if (ret = SOCKET_ERROR | ret = 0)return false;/接收服务器返回的邮箱信息msgLen = recv(pClient,msgBuf,500,0);if (msgLen = SOCKET_ERROR | msgLen = 0)return false;if (strncmp(msgBuf,+OK,3) != 0) /服务器返回非+OK表示用户请求失败return

14、false;msgBufmsgLen = 0;int mCount; /记录邮件的个数int sMail; /记录邮件的长度sscanf(msgBuf,+OK %d %d,&mCount,&sMail);for (int i = 1; i = mCount; i+)/向服务器发送邮件i信息的请求sprintf(msgBuf,LIST %drn,i);ret = send(pClient,msgBuf,strlen(msgBuf),0);if (ret = SOCKET_ERROR | ret = 0)return false;/接收服务器返回的信息msgLen = recv(pClient,m

15、sgBuf,500,0);if (msgLen = SOCKET_ERROR | msgLen = 0)return false;if (strncmp(msgBuf,+OK,3) != 0) /服务器返回非+OK表示用户请求失败return false;msgBufmsgLen = 0;int iFlag; /获取邮箱标示 sscanf(msgBuf,+OK %d %d,&iFlag,&sMail);/请求接收邮箱i的内容sprintf(msgBuf,RETR %drn,i);ret = send(pClient,msgBuf,strlen(msgBuf),0);if (ret = SOCK

16、ET_ERROR | ret = 0)return false;/接收服务器返回的信息msgLen = recv(pClient,msgBuf,6,0);if (msgLen = SOCKET_ERROR | msgLen = 0)return false;if (strncmp(msgBuf,+OK,3) != 0) /服务器返回非+OK表示用户请求失败return false;char * mailBuff = new char sMail+15; /用于接收邮件内容msgLen = RecvData(mailBuff,sMail+14);if (msgLen = SOCKET_ERROR

17、 | msgLen = 0)return false;mailBuffmsgLen = 0;MailInfo mailInfo;StringToStruct(mailBuff,mailInfo);m_Info.push_back(mailInfo);delete mailBuff;return true;删除邮件向服务器发送DELE x命令,删除邮件x,但是要在执行QUIT命令后才真正的删除邮件char msgBuf501; /用于存储删除字符串和接收字符串int ret; /记录函数执行返回值int msgLen; /发送或接受字符串长度/向服务器发送请求邮箱信息sprintf(msgBuf

18、,DELE %drn,index);ret = send(pClient,msgBuf,strlen(msgBuf),0);if (ret = SOCKET_ERROR | ret = 0)return false;/接收服务器返回的邮箱信息msgLen = recv(pClient,msgBuf,500,0);if (msgLen = SOCKET_ERROR | msgLen = 0)return false;if (strncmp(msgBuf,+OK,3) != 0) /服务器返回非+OK表示用户请求失败return false;msgBufmsgLen = 0;return true

19、;退出登录的pop3服务器向服务器发送QUIT命令char msgBuf501; /用于存储退出字符串和接收字符串int ret; /记录函数执行返回值int msgLen; /发送或接受字符串长度/向服务器发送请求邮箱信息sprintf(msgBuf,QUITrn);ret = send(pClient,msgBuf,strlen(msgBuf),0);if (ret = SOCKET_ERROR | ret = 0)return false;/接收服务器返回的邮箱信息msgLen = recv(pClient,msgBuf,500,0);if (msgLen = SOCKET_ERROR

20、| msgLen = 0)return false;if (strncmp(msgBuf,+OK,3) != 0) /服务器返回非+OK表示用户请求失败return false;msgBufmsgLen = 0;return true;quoted解码 int nDstLen; / 输出的字符计数 int i; i = 0; nDstLen = 0; while (i nSrcLen) if (strncmp(pSrc, =rn, 3) = 0) / 软回车,跳过 pSrc += 3; i += 3; else if (*pSrc = =) / 是编码字节 if (!strncmp(pSrc,

21、 =A8, 3)int sd = 5; sscanf(pSrc, =%02X, pDst); pDst+; pSrc += 3; i += 3; else / 非编码字节 *pDst+ = (unsigned char)*pSrc+; i+; nDstLen+; / 输出加个结束符 *pDst = 0;return nDstLen;base64解码short nDecTab256;short i;UINT buf;int nOffset, len = strlen(szCoded);char *p = (char *)szCoded; BYTE *r = pOut;memset(nDecTab, -1, sizeof(short) * 256);for(i = 0; i 3 * 8if(p + 4 - szCoded = len)buf = (nDecTab*p & 0 x3F) 18) | (nDecTab*(p + 1) & 0 x3

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论