最近做网络程序设计大作业,选做的邮件客户端,以前做的都是TCP、UDP方面的,还有就是利用winpcap包写抓包程序,在应用层上还没有做过,所以利用这个机会学习一下。发现在应用层上好像还简单一点,不用自己制定协议,只要服务现有的协议就行了,当然我说的是现有的,例如SMTP,POP,IMAP,FTP等,,其他没做过,所以说的可能不全面吧,还请大神指教。(第一篇博客,写的肯定很垃圾,希望前辈们给予指导)
(smtp)首先要了解SMTP协议的实现过程,如下图(这个图可以是我根据我自己写的程序画的,基本与实际符合)
这里我没有给出出现错误时,服务器返回的代码,这个可以自己查找。在这里我个人感觉,重点就是:
(1)了解SMTP协议过程
(2)发送命令的格式,当时我就是这点出了问题,搞了很长时间才找出问题。例如,每个命令都要以“\r\n”结尾,而且命令与结尾之间不能有空格等,当我发送用户名时,用数组name[]储存的,然后用sizeof计算数组长度,然后再name[len]='\r';name[len+1]='\n';结果发过去一直不对,最后才发现需要用strlen计算长度,因为sizeof实际上获得的是当初声明数组是给定的长度,并非你的邮箱地址的长度;另外,当发过"DATA"命令后,在你发送内容时,需要有个subject(自己加),否则会出问题,这个我不知道为什么,
这个当初我是通过用outlook发送邮件,然后wireshark抓包发现有这个字符串的,可能是与邮箱的具体实现有关吧
(3)base64编码,,我实现的可能有点麻烦,,可以参考别人的
代码(代码写的不是太好):
#include <iostream>
#include <string>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
using namespace::std;
#define PORT 25
#define SINA "smtp.sina.com.cn"
#define QQ "smtp.qq.com"
#define W163 "smtp.163.com"
#define W126 "smtp.126.com"
SOCKET clsock;
char smtpname[256];
char code[100];
int base64code(char str[]);
char base64(char a);
int main()
{
//创建套接字
WSAData wsadata;
WSAStartup(WINSOCK_VERSION,&wsadata);
clsock=socket(AF_INET,SOCK_STREAM,0);
if(clsock==INVALID_SOCKET)
{
WSACleanup();
return -1;
}
//选择邮箱
int num;
memset(smtpname,0,256);
cout<<"***************选择邮箱******************"<<endl;
cout<<"请选择邮箱:"<<endl;
cout<<"新浪--1 QQ--2 网易163--3 网易126--4"<<endl;
cout<<"******************************************"<<endl;
cin>>num;
switch(num)
{
case 1:memcpy(smtpname,SINA,sizeof(SINA));
break;
case 2:memcpy(smtpname,QQ,sizeof(QQ));
break;
case 3:memcpy(smtpname,W163,sizeof(W163));
break;
case 4:memcpy(smtpname,W126,sizeof(W126));
break;
}
//连接至服务器
struct sockaddr_in smtpserver;
hostent *hostinfo;
hostinfo=gethostbyname(smtpname);
memset(&smtpserver,0,sizeof(sockaddr_in));
smtpserver.sin_family=AF_INET;
smtpserver.sin_port=htons(PORT);
memcpy(&smtpserver.sin_addr.S_un.S_addr,hostinfo->h_addr_list[0],hostinfo->h_length);
if(connect(clsock,(struct sockaddr *)&smtpserver,sizeof(sockaddr_in))==SOCKET_ERROR)
{
cout<<"error:"<<WSAGetLastError()<<endl;
}
char buf[1000]={0};
memset(buf,0,1000);
recv(clsock,buf,1000,0);
cout<<"**************连接至服务器*******************"<<endl;
cout<<"connect info:"<<endl<<buf<<endl;
cout<<"*********************************************"<<endl;
//问候收件方
//memset(buf,0,1000);
//memcpy(buf,"EHLO eSam613@163.com\r\n",strlen("EHLO eSam613@163.com\r\n"));
send(clsock,"EHLO WIN99FNGAENFOD\r\n",strlen("EHLO WIN99FNGAENFOD\r\n"),0);
//cout<<sizeof("EHLO WIN99FNGAENFOD")<<" "<<strlen("EHLO WIN99FNGAENFOD ");
memset(buf,0,1000);
recv(clsock,buf,1000,0);
cout<<"***************问候收件方******************"<<endl;
cout<<&