您好,欢迎来到微智科技网。
搜索
您的当前位置:首页计算机网络实验SMTP邮件发送系统socket编程

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

来源:微智科技网
 实验四 邮件客户端实现

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

与因特网连接的计算机网络系统; 主机操作系统为Windows7; VC6

[实验内容]::要求学生利用已有的套接字常识使用SMTP和POP3的任一

种协议,实现对于特定邮件服务器(mail.163)的发送邮件功能。

[实验步骤]:

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

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@gmail.com\";

char title[]=\"test\";

char body[]=\"heshanshan09211595\"; char strServer[]=\"SMTP.163.com\";

char strUser[]=\"shan_shan2512\"; char strPsw[]=\"shanshan091756\";

char strSndMail[]=\"shan_shan2512@163.com\";*/ //提示输入的信息 printf(\"strServer:\");scanf(\"%s\printf(\"strSndMail:\");scanf(\"%s\printf(\"strUser:\");scanf(\"%s\printf(\"strPsw:\");scanf(\"%s\

printf(\"to:\");scanf(\"%s\printf(\"title:\");scanf(\"%s\printf(\"body:\");scanf(\"%s\

if (smtp.MailSend(to,title,body,strServer,strUser,strPsw,strSndMail)) { } SMTP.h: #pragma once #include #include \"Base.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:

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

}

else { } return 0;

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

#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\ printf(\"%s\\n\ 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\//将用户名赋给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,如果是,表示此时可以输入位编码过的用户名了 if(position == 0) {

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

string strTmp = Base::base_encode(dst,len);//进行位编码

len = sprintf((char*)s,\"%s\\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(\"334\"); if(position == 0) {

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

string strTmp = Base::base_encode(dst,len);

len = sprintf((char*)s,\"%s\\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(\"235\"); if(position == 0) {

len = sprintf((char*)s,\"MAIL FROM: <%s>\\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; }

//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\//发送要发送的邮箱的地址

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\\nTo: %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\ 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-Transfer-Encoding: %s\\r\\n\\r\\n%s\\r\\n\\r\\n\charset=gb2312\ len = send(m_socket,s,strlen(s),0);

//邮件结束

sprintf((char*)s,\"\\r\\n--%s--\\r\\n.\\r\\n\ 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\");

if(position == 0) {

if(m_socket)

closesocket(m_socket); m_socket = NULL; } 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; }

return TRUE; }

Base.cpp:

#include \"StdAfx.h\" #include \"Base.h\"

static const std::string base_chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" \"abcdefghijklmnopqrstuvwxyz\" \"01234567+/\";

std::string

Base::base_encode(unsigned

unsigned int in_len) {

std::string ret; int i = 0; int j = 0;

unsigned char char_array_3[3]; unsigned char char_array_4[4];

char

const*

bytes_to_encode,

while (in_len--) {

char_array_3[i++] = *(bytes_to_encode++); if (i == 3) {

char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;

char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);

char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);

char_array_4[3] = char_array_3[2] & 0x3f;

for(i = 0; (i <4) ; i++)

ret += base_chars[char_array_4[i]]; i = 0; } } if (i) {

for(j = i; j < 3; j++) char_array_3[j] = '0';

char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;

char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);

char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);

char_array_4[3] = char_array_3[2] & 0x3f;

for (j = 0; (j < i + 1); j++)

ret += base_chars[char_array_4[j]];

while((i++ < 3)) ret += '='; }

return ret; }

std::string Base::base_decode(std::string const& encoded_string) {

int in_len = encoded_string.size(); int i = 0; int j = 0;

int in_ = 0;

unsigned char char_array_4[4], char_array_3[3]; std::string ret;

while

(in_len--

&&

(

encoded_string[in_]

!=

'=')

&&

is_base(encoded_string[in_])) {

char_array_4[i++] = encoded_string[in_]; in_++; if (i ==4) {

for (i = 0; i <4; i++)

char_array_4[i] = base_chars.find(char_array_4[i]);

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);

char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);

char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (i = 0; (i < 3); i++) ret += char_array_3[i]; i = 0; } }

if (i) {

for (j = i; j <4; j++) char_array_4[j] = 0;

for (j = 0; j <4; j++)

char_array_4[j] = base_chars.find(char_array_4[j]);

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);

char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; }

return ret; }

输出:

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 7swz.com 版权所有 赣ICP备2024042798号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务