计算机网络实验SMTP邮件发送系统socket编程

计算机网络实验SMTP邮件发送系统socket编程
计算机网络实验SMTP邮件发送系统socket编程

实验四邮件客户端实现

1316-30-何珊珊[实验名称]:邮件客户端实现

[实验器材]:

与因特网连接的计算机网络系统;

主机操作系统为Windows7;

VC6

[实验内容]::要求学生利用已有的套接字常识使用SMTP和POP3的任一种协议,实现对于特定邮件服务器(mail.163)的发送邮件功能。

[实验步骤]:

在VC6中搭建工程,因为SMTP中用户名和密码都要经过64位编码的处理,所以工程中除了对SMTP的编程外还需要一个64为编码的转换函数。以下是代码:

MailTest.cpp:

#include "stdafx.h"

#include "SMTP.h"

int main(int argc, char* argv[])

{

char to[256];char title[256];char body[1024];char strServer[128];char strUser[128];char strPsw[128];char strSndMail[128];

CSMTP smtp;

smtp.Initialize();

/*char to[]="heshanshan2512@https://www.360docs.net/doc/e717386851.html,";

char title[]="test";

char body[]="heshanshan09211595";

char strServer[]="https://www.360docs.net/doc/e717386851.html,";

char strUser[]="shan_shan2512";

char strPsw[]="shanshan091756";

char strSndMail[]="shan_shan2512@https://www.360docs.net/doc/e717386851.html,";*/ //提示输入的信息

printf("strServer:");scanf("%s",strServer);

printf("strSndMail:");scanf("%s",strSndMail);

printf("strUser:");scanf("%s",strUser);

printf("strPsw:");scanf("%s",strPsw);

printf("to:");scanf("%s",to);

printf("title:");scanf("%s",title);

printf("body:");scanf("%s",body);

if (smtp.MailSend(to,title,body,strServer,strUser,strPsw,strSndMail))

{

printf("successful\n"); //发送成功

}

else

{

printf("fail\n"); //发送失败

}

return 0;

}

SMTP.h:

#pragma once

#include

#include "Base64.h"

#include

#pragma comment(lib, "Ws2_32")

#include

#include

using namespace std;

class CSMTP

{

public:

CSMTP(void);

~CSMTP(void);

BOOL Initialize(void);

BOOL MailSend(string to, string title, string body, string strServer, string strUser, string strPsw, string strSndMail);

private:

SOCKET m_socket;

};

SMTP.cpp:

#include "stdafx.h"

#include "SMTP.h"

#define MAX_PACKET_SIZE 1024

CSMTP::CSMTP(void) //构造函数{

m_socket = NULL;

}

CSMTP::~CSMTP() //析构函数{

}

BOOL CSMTP::Initialize() //入口函数

{

WORD wVersionRequested; //用WSAStartup函数加载套接字库,并进行版本协商

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 )

{

return FALSE;

}

if ( LOBYTE( wsaData.wVersion ) != 1 ||

HIBYTE( wsaData.wVersion ) != 1 )

{

WSACleanup();

return FALSE;

}

return TRUE;

}

BOOL CSMTP::MailSend(string to, string title, string body, string strServer, string strUser, string strPsw, string strSndMail)

{

sockaddr_in addrSmtp; //配置服务端地址信息

const char *smtpServer = strServer.c_str();

const char *smtpUser = strUser.c_str();

const char *smtpPass = strPsw.c_str();

const char *senderMail = strSndMail.c_str();

if(m_socket != NULL) //判断socket是否可用,若不可用重新创建

{

closesocket(m_socket);

m_socket = NULL;

}

if(m_socket == NULL)

{

m_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//创建一个客户端的套接字

}

struct in_addr in;

hostent *hosts = gethostbyname(smtpServer); //域名转换

if (hosts != NULL)

{

memcpy((char**)&(in),hosts->h_addr,hosts->h_length); //把主机地址付给in }

else

{

return FALSE;

}

string addrc = inet_ntoa(in);//将网络字节序转换成应用的格式

addrSmtp.sin_family = AF_INET; //配置服务端地址信息

addrSmtp.sin_addr.s_addr = in.S_un.S_addr;

addrSmtp.sin_port = htons(25); //SMTP的端口号为25

int ret = 0;

ret = connect(m_socket, (LPSOCKADDR)&addrSmtp, sizeof(addrSmtp)); //与服务端进行连接

if(ret == SOCKET_ERROR)//连接失败

{

char *err = new char[1024];

sprintf(err,"连接失败%d",GetLastError());

printf("%s\n",err);

return FALSE;

}

char s[MAX_PACKET_SIZE];

char r[MAX_PACKET_SIZE];

memset((void*)s,0,MAX_PACKET_SIZE);

memset((void*)r,0,MAX_PACKET_SIZE);

int len;

string response;

//等待服务器回应

len = recv(m_socket,(char*)r,MAX_PACKET_SIZE,0);

if(len)

{

response = r;

int position = response.substr(0,3).compare("220");//判断返回信息的前三个字符是否为220,如果是,表示连接服务器成功

if(position == 0)

{

len = sprintf((char*)s,"helo %s\r\n", strUser.c_str());//将用户名赋给s并发送给服务器

len = send(m_socket,s,strlen(s),0);

}

else

{

printf(r);

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

return FALSE;

}

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

return FALSE;

}

len = recv(m_socket,(char*)r,MAX_PACKET_SIZE,0);//接收服务器返回的信息

if(len)

{

response = r;

int position = response.substr(0,3).compare("250");//判断返回信息的前三个字符是否为250,如果是,表示此时可以登录了

if(position == 0)

{

len = sprintf((char*)s,"AUTH LOGIN\r\n");//将要登陆的命令发送给服务器

len = send(m_socket,s,strlen(s),0);

}

else

{

printf(r);

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

return FALSE;

}

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

return FALSE;

}

//等待登录回应

len = recv(m_socket,(char*)r,MAX_PACKET_SIZE,0); //接收服务器返回的信息

if(len)

{

response = r;

int position = response.substr(0,3).compare("334");//判断返回信息的前三个字符是否为334,如果是,表示此时可以输入64位编码过的用户名了

if(position == 0)

{

unsigned char *dst = (unsigned char*)smtpUser;

len = strlen((char*)dst);

string strTmp = Base64::base64_encode(dst,len);//进行64位编码

len = sprintf((char*)s,"%s\r\n",(const char*)strTmp.c_str());

len = send(m_socket,s,strlen(s),0);//发送编码过的用户名

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

printf(r);

return FALSE;

}

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

return FALSE;

}

//发送完用户名后等待回应

len = recv(m_socket,(char*)r,MAX_PACKET_SIZE,0);//发送编码过的密码,代码和发

送用户名时的方式类似

if(len)

{

response = r;

int position = response.substr(0,3).compare("334");

if(position == 0)

{

unsigned char *dst = (unsigned char*)smtpPass;

len = strlen((char*)dst);

string strTmp = Base64::base64_encode(dst,len);

len = sprintf((char*)s,"%s\r\n",(const char*)strTmp.c_str());

len = send(m_socket,s,strlen(s),0);

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

printf(r);

return FALSE;

}

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

return FALSE;

}

//发送完密码后等待回应看是否登录成功

len = recv(m_socket,(char*)r,MAX_PACKET_SIZE,0);

if(len)

{

response = r;

int position = response.substr(0,3).compare("235");

if(position == 0)

{

len = sprintf((char*)s,"MAIL FROM: <%s>\r\n",senderMail);

len = send(m_socket,s,strlen(s),0); //发送本地邮箱的地址}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

printf(r);

return FALSE;

}

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

return FALSE;

}

//header部份

len = recv(m_socket,(char*)r,MAX_PACKET_SIZE,0);

if(len)

{

response = r;

int position = response.substr(0,3).compare("250");

if(position == 0)

{

len = sprintf((char*)s,"RCPT TO: <%s>\r\n",to.c_str());//发送要发送的邮箱的地址

len = send(m_socket,s,strlen(s),0);

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

printf(r);

return FALSE;

}

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

return FALSE;

}

//header部份

len = recv(m_socket,(char*)r,MAX_PACKET_SIZE,0);

if(len)

{

response = r;

int position = response.substr(0,3).compare("250");

if(position == 0)

{

len = sprintf((char*)s,"DATA\r\n");//发送data向服务器发送邮件内容的申请

len = send(m_socket,s,strlen(s),0);

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

printf(r);

return FALSE;

}

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

return FALSE;

}

len = recv(m_socket,(char*)r,MAX_PACKET_SIZE,0);

if(len)

{

response = r;

int position = response.substr(0,3).compare("354");

if(position == 0)

{

char date_string[MAX_PACKET_SIZE];

time_t seconds;//调用本地时间

time(&seconds);

strftime(date_string, MAX_PACKET_SIZE,

"%a, %d %b %y %H:%M:%S +0800",

localtime(&seconds));

sprintf((char*)s,"From: %s\r\nT o: %s\r\nDate: %s\r\nSubject: %s\r\n\r\nX-Mailer: %s\r\ nX-Priority: %s\r\nMIME-Version: 1.0\r\nContent-type: multipart/mixed;

boundary=\"%s\"\r\n\r\n",

senderMail,to.c_str(),date_string,title.c_str(),"SMailer","3","#BOUNDARY#");

len = send(m_socket,s,strlen(s),0);

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

printf(r);

return FALSE;

}

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

return FALSE;

}

//邮件正文

sprintf((char*)s,"--%s\r\nContent-Type: %s\r\nContent-Disposition: %s\r\nContent-Tran sfer-Encoding: %s\r\n\r\n%s\r\n\r\n","#BOUNDARY#","text/plain;

charset=gb2312","","8bit",body.c_str());

len = send(m_socket,s,strlen(s),0);

//邮件结束

sprintf((char*)s,"\r\n--%s--\r\n.\r\n","#BOUNDARY#");

len = send(m_socket,s,strlen(s),0);

len = recv(m_socket,(char*)r,MAX_PACKET_SIZE,0);

if(len)

{

response = r;

int position = response.substr(0,3).compare("250");

if(position == 0)

{

//退出连接

sprintf((char*)s,"QUIT\r\n");

len = send(m_socket,s,strlen(s),0);

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

printf(r);

return FALSE;

}

}

else

{

if(m_socket)

closesocket(m_socket);

m_socket = NULL;

return FALSE;

}

//断开连接

len = recv(m_socket,(char*)r,MAX_PACKET_SIZE,0);

if(len)

{

response = r;

int position = response.substr(0,3).compare("221");

相关主题
相关文档
最新文档