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 #pragma comment(lib, \"Ws2_32\") #include 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
本站由北京市万商天勤律师事务所王兴未律师提供法律服务