今日得闲,于是将POP3的学习笔记也整理出来!

互联网上的TCP/IP,POP3/SMTP等资料多如牛毛,这里只是自己一点点心得,另外对于各位网络方面的大牛请安静的路过,我可不喜欢在关公面前耍大刀...

(还是那句,我比较喜欢用实践来证明一切,这样才会加深自己的理解!)

 一、准备工作:

1、本机环境:Windows XP SP3、公司ADSL 10M光纤

2、开发工具:WildPackets OmniPeek V5.1.4

                    Visual C++ 6.0

                    Outlook Express6.0

                    FlexEdit V2.3.1871

 二、SMTP命令:
1、USER username
2、PASS password
3、STAT 请求服务器发回关于邮箱的统计资料,如邮件总数和总字节数
4、LIST 返回邮件数量和每个邮件的大小
5、RETR [Msg#] 返回由参数标识的邮件的全部文本
6、DELE [Msg#] 服务器将由参数标识的邮件标记为删除,由quit命令执行
7、RSET 服务器将重置所有标记为删除的邮件,用于撤消DELE命令
8、NOOP 服务器返回一个肯定的响应
9、QUIT 更新

三、分析数据包:

1、打开Outlook Express6.0,选择POP协议,内容如下:

POP3协议学习笔记_socket

 

2、开始捕获后点击“接收邮件”,内容如下:

POP3协议学习笔记_服务器_02

 

3、前面的数据包信息、以太网信息、IP头、TCP头就不用介绍了吧!

 

     数据包中包含到的命令都打圈标记了,下面是LIST返回的数据包:

POP3协议学习笔记_express_03

 

4、下面是UIDL返回的数据包,邮件唯一的标示:

POP3协议学习笔记_express_04

 

5、其他小技巧

     <CR> <LF>即对应C/C++中的"/r /n"

四、相关代码:

1、以下代码通过socket与POP3服务器建立连接并读取邮件列表、原文等。

 

     打开Visual C++,新建一个控制台工程、并添加一个CPP文件

 

 

/************************************************************************/
/* main.cpp  POP3协议学习笔记 - 连接POP3、读取邮件列表、读取邮件原文
/* by Koma 2009.9.10 14:10
/************************************************************************/
#include "stdio.h" 
#include "winsock2.h"   
#pragma	comment(lib,"ws2_32.lib")   

int main(int argc, char* argv[])
{
	SOCKADDR_IN	saServer;
	LPHOSTENT	lphostent;
	WSADATA		wsadata;
	SOCKET		hsocket;
	
	int		nRet;
	char*   host_name="pop.tom.com";
	char*   req=
		// 两行是登录用户与密码(以明文的方式发送)
		"USER ningyusky@tom.com/r/n"
		"PASS w*****/r/n"
		"STAT/r/n"		// 获取信箱状态
		"LIST/r/n"		// 获取所以邮件列表信息
		"UIDL 1/r/n"	// 获取邮件1的唯一标识符
		"RETR 3/r/n"	// 从服务器读取出邮件3原文
		"QUIT/r/n";		// 退出连接
	
	// 初始化套接字
	if(WSAStartup(MAKEWORD(2,2),&wsadata))   
		printf("初始化SOCKET出错!");
	
	// SMTP端口默认是110
	lphostent=gethostbyname(host_name);   
	if(lphostent==NULL)   
		printf("lphostent为空!");
	hsocket   =   socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);   
	saServer.sin_family = AF_INET;   
	saServer.sin_port = htons(110);   
	saServer.sin_addr = *((LPIN_ADDR)*lphostent->h_addr_list);
	
	// 利用SOCKET连接
	nRet = connect(hsocket,(LPSOCKADDR)&saServer,sizeof(SOCKADDR_IN));   
	if(nRet == SOCKET_ERROR)   
	{   
		printf("建立连接时出错!/n");   
		closesocket(hsocket);   
		return 0;   
	}
	
	// 利用SOCKET发送
	nRet = send(hsocket,req,strlen(req),0);
	if(nRet==SOCKET_ERROR)
	{
		printf("发送数据包时出错!");
		closesocket(hsocket);
	}
	
	char   Dest[20000];
	memset(Dest,0,20000);
	nRet=1;   
	while(nRet>0)   
	{
		// 接收返回数据包
		nRet=recv(hsocket,(LPSTR)Dest,sizeof(Dest),0);   
		if(nRet>0)   
			Dest[nRet]=0;   
		else   
			Dest[0]=0;
		// 显示返回数据包的大小、内容
		printf("/n返回数据包大小:%d/n",nRet);   
		printf("返回数据包内容:/n%s",Dest);   
	}
	return 0;
}

 

2、程序运行效果:

POP3协议学习笔记_开发工具_05