SMTPsend.cpp
// ntSendMail.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdlib.h> #include "winsock2.h" #include "base64.h" #include <sys/stat.h> #include <time.h> #include <io.h> //winsock 2.2 library #pragma comment(lib,"ws2_32.lib") #define SMTP_PORT 25 // Standard port for SMTP servers #define RESPONSE_BUFFER_SIZE 1024 #define PARA_BUF 128 #define RESPONSE_NUM 6 #define _T(x) x // Helper Code struct response_code { UINT nResponse; // Response we're looking for TCHAR* sMessage; // Error message if we don't get it }; enum eResponse { GENERIC_SUCCESS = 0, AUTHLOGIN_SUCCESS, AUTH_SUCCESS, CONNECT_SUCCESS, DATA_SUCCESS, QUIT_SUCCESS, LAST_RESPONSE }; TCHAR *response_buf; static response_code response_table[RESPONSE_NUM]= { //GENERIC_SUCCESS {250, _T("SMTP 服务器错误")}, //AUTHLOGIN_SUCCESS {334, _T("SMTP 验证连接错误")}, //AUTH_SUCCESS {235, _T("SMTP 用户名/密码验证错误")}, //CONNECT_SUCCESS {220, _T("SMTP 服务器不可用")}, //DATA_SUCCESS {354, _T("SMTP 服务器不能接收数据")}, //QUIT_SUCCESS {221, _T("SMTP 没有中止会话")} }; typedef struct _tagCONFIG_INFO { char m_szServerName[PARA_BUF]; char m_nPort[1]; char m_nNeedAuth[1]; char m_szAccount[PARA_BUF]; char m_szPassword[PARA_BUF]; char m_szFrom[PARA_BUF]; char m_szTo[PARA_BUF]; char m_szUsername[PARA_BUF]; char m_szFilename[PARA_BUF*2]; char m_szSubject[PARA_BUF]; char m_szBody[1024]; }CONFIG_INFO, * LPCONFIG_INFO; SOCKET sconnection; CONFIG_INFO ci; BOOL AuthorizationLogin(); BOOL GetResponse(UINT response_expected); BOOL SendMail(); int main(int argc, char* argv[]) { WSADATA wsock; SOCKADDR_IN serAddr; int nRet=0; //初始化Winsock 2.2 printf("\nInitialising Winsock...\n"); if (WSAStartup(MAKEWORD(2,2),&wsock) != 0) { fprintf(stderr,"WSAStartup() failed %d\n, WSAGetLastError()"); exit(0); } printf("Initialised successfully.\n"); //创建监听socket printf("\nCreating TCP Socket...\n"); if ((sconnection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { printf("Creation of socket failed %d\n", WSAGetLastError()); WSACleanup(); return 0; } printf("TCP Socket Created successfully.\n"); ZeroMemory(&ci,sizeof(CONFIG_INFO)); //邮件服务器 sprintf(ci.m_szServerName,"smtp.126.com"); //设置SOCKADDR_IN地址结构 serAddr.sin_family = AF_INET; serAddr.sin_port = htons(SMTP_PORT); //From CAsyncSocket::Connect serAddr.sin_addr.s_addr = inet_addr(ci.m_szServerName); if (serAddr.sin_addr.s_addr == INADDR_NONE) { LPHOSTENT lphost; lphost = gethostbyname(ci.m_szServerName); if (lphost != NULL) serAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr; else { WSASetLastError(WSAEINVAL); return 0; } } //连接服务端 printf("Connecting to %s:%d...\n", inet_ntoa(serAddr.sin_addr), htons(serAddr.sin_port)); if (connect(sconnection, (SOCKADDR *) &serAddr, sizeof(serAddr)) == SOCKET_ERROR) { printf("connection failed with error %d\n", WSAGetLastError()); closesocket(sconnection); WSACleanup(); return 0; } printf("connection successfully.\n"); response_buf = new TCHAR[RESPONSE_BUFFER_SIZE]; if(!GetResponse(CONNECT_SUCCESS)) { closesocket(sconnection); delete response_buf; response_buf = NULL; return FALSE; } //发送“EHLO %SMTP-Server Name%”: char szHello[PARA_BUF]; sprintf(szHello,_T("EHLO %s\r\n"),ci.m_szServerName); send(sconnection,szHello,strlen(szHello),0); if(!GetResponse(GENERIC_SUCCESS)) { printf("Cann't connect the server!\n"); closesocket(sconnection); delete response_buf; response_buf = NULL; return FALSE; } //用户名、密码 printf("Enter Account name: \n"); sprintf(ci.m_szAccount,"nuaa0406104"); printf("Enter passwd: \n"); sprintf(ci.m_szPassword,"nuaa0406104"); printf("Enter Sender Email: "); sprintf(ci.m_szFrom,"[email protected]"); printf("Enter Subject: \n"); sprintf(ci.m_szSubject,"三少爷彻底放下了"); printf("Enter Receiver Email: \n"); sprintf(ci.m_szTo,"[email protected]"); printf("Enter User name: \n"); sprintf(ci.m_szUsername,"Jimmy Won"); printf("Enter Email Content: \n"); sprintf(ci.m_szBody,"自从发现了某人与山哥走在一起,三少爷彻底放下了。"); printf("Enter Attachment name: "); sprintf(ci.m_szFilename,"Readme.txt"); if(AuthorizationLogin()) { printf("Authorized ok\n"); if(SendMail()) printf("Send ok!\n"); } printf("Closing the connection.\n"); closesocket(sconnection); WSACleanup(); getchar(); return 0; } //**************************************** // 函数功能:服务器验证 //**************************************** BOOL AuthorizationLogin() { char* szAccount; char* szPassword; printf("Authing......\n "); //发送“AUTH LOGIN”: send(sconnection,_T("AUTH LOGIN\r\n"), strlen(_T("AUTH LOGIN\r\n")),0); if(!GetResponse(AUTHLOGIN_SUCCESS)) { closesocket(sconnection); delete response_buf; response_buf = NULL; return FALSE; } //发送经过Base64编码的用户帐号: base64_encode(ci.m_szAccount,strlen(ci.m_szAccount),&szAccount); // char buf[200]; // base64_decode(szAccount,buf); //注意添加回车换行 strcat(szAccount,"\r\n"); send(sconnection,szAccount,strlen(szAccount),0); if(!GetResponse(AUTHLOGIN_SUCCESS)) { closesocket(sconnection); delete response_buf; response_buf = NULL; return FALSE; } //发送经过Base64编码的用户密码 base64_encode(ci.m_szPassword,strlen(ci.m_szPassword),&szPassword); strcat(szPassword,"\r\n"); send(sconnection,szPassword,strlen(szPassword),0); if(!GetResponse(AUTH_SUCCESS)) { closesocket(sconnection); delete response_buf; response_buf = NULL; return FALSE; } return TRUE; } //**************************************** // 函数功能:获得服务器返回信息 //**************************************** BOOL GetResponse(UINT response_expected) { char szResponse[RESPONSE_BUFFER_SIZE]; UINT response; response_code *pResp; int recvCount = 0; if((recvCount=recv(sconnection,response_buf, RESPONSE_BUFFER_SIZE,0)) == SOCKET_ERROR) { return FALSE; } response_buf[recvCount]='\0'; printf("\n*********** Response *************\n"); printf("%s\n",response_buf); sscanf(szResponse, _T("%d"), &response); strncpy(szResponse,response_buf,3); sscanf(szResponse, _T("%d"), &response); pResp = &response_table[response_expected]; if(response != pResp->nResponse) { printf(_T("%d:%s"), response, (LPCTSTR)pResp->sMessage); return FALSE; } return TRUE; } //**************************************** // 函数功能:生成并传输邮件内容 //**************************************** BOOL SendMail() { char szFrom[PARA_BUF]={0},szTo[PARA_BUF]={0},szSubject[PARA_BUF]={0},szBodyHead[PARA_BUF*10]={0}; char szBody[PARA_BUF*20]={0},szContent[PARA_BUF*80]={0},szAttachment[PARA_BUF*10]={0},szTemp[PARA_BUF*50]={0}; char szDateTime[PARA_BUF]={0},szFileBuf[1024*5]={0}; printf("Sending Mail......\n "); //发送Header中的“MAIL FROM” sprintf(szFrom,_T("MAIL FROM:<%s>\r\n"),ci.m_szFrom); send(sconnection,szFrom,strlen(szFrom),0); if(!GetResponse(GENERIC_SUCCESS)) { closesocket(sconnection); delete response_buf; response_buf = NULL; return FALSE; } //发送Header中的“RCPT TO” sprintf(szTo,_T("RCPT TO:<%s>\r\n"),ci.m_szTo); send(sconnection,szTo,strlen(szTo),0); if(!GetResponse(GENERIC_SUCCESS)) { closesocket(sconnection); delete response_buf; response_buf = NULL; return FALSE; } //发送“DATA\r\n” send(sconnection,"DATA\r\n",strlen("DATA\r\n"),0); if(!GetResponse(DATA_SUCCESS)) { closesocket(sconnection); delete response_buf; response_buf = NULL; return FALSE; } //以下进行 Body 的处理 sprintf(szFrom,_T("FROM:%s<%s>\r\n"),ci.m_szUsername,ci.m_szFrom); sprintf(szTo,_T("TO:<%s>\r\n"),ci.m_szTo); time_t ltime=time(NULL); _tzset(); sprintf(szDateTime,"Date:%s",ctime(<ime)); sprintf(szSubject,_T("Subject:%s\r\n"),ci.m_szSubject); sprintf(szBodyHead,_T("X-Mailer: ntSmtp [ch]\r\n")); strcat(szBodyHead,"MIME_Version:1.0\r\n"); strcat(szBodyHead,"Content-type:multipart/mixed;Boundary=ntSmtp\r\n\r\n"); strcat(szBodyHead,"--ntSmtp\r\n"); strcat(szBodyHead,"Content-type:text/plain;Charset=gb2312\r\n"); strcat(szBodyHead,"Content-Transfer-Encoding:8bit\r\n\r\n"); sprintf(szBody,_T("%s\r\n\r\n"),ci.m_szBody); //以下进行附件的处理 if(!_access(ci.m_szFilename,0)) { sprintf(szTemp,"--ntSmtp\r\n"); strcat(szTemp,"Content-Type:application/octet-stream;Name=%s\r\n"); strcat(szTemp,"Content-Disposition:attachment;FileName=%s\r\n"); strcat(szTemp,"Content-Transfer-Encoding:Base64\r\n\r\n"); strcat(szTemp,"%s\r\n\r\n"); sprintf(szContent,szFrom); strcat(szContent,szTo); strcat(szContent,szDateTime); strcat(szContent,szSubject); strcat(szContent,szBodyHead); strcat(szContent,szBody); HANDLE hFile; hFile=CreateFile(ci.m_szFilename,GENERIC_READ,FILE_SHARE_READ, NULL ,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile!=INVALID_HANDLE_VALUE) { struct _stat filestat; _stat(ci.m_szFilename,&filestat); DWORD dwNum; ReadFile(hFile,szFileBuf,filestat.st_size,&dwNum,NULL); char* file; base64_encode(szFileBuf,strlen(szFileBuf),&file); char fname[100]={0}; char ext[3]={0}; _splitpath(ci.m_szFilename,NULL,NULL,fname,ext); strcat(fname,ext); sprintf(szAttachment,szTemp,fname,fname,file); CloseHandle(hFile); strcat(szContent,szAttachment); } //连接成Content strcat(szContent,"--ntSmtp\r\n.\r\n"); } else { //连接成 Content strcat(szContent,szFrom); strcat(szContent,szTo); strcat(szContent,szDateTime); strcat(szContent,szSubject); strcat(szContent,szBodyHead); strcat(szContent,szBody); strcat(szContent,"--ntSmtp\r\n.\r\n"); } //发送 Content send(sconnection,szContent,strlen(szContent),0); if(!GetResponse(GENERIC_SUCCESS)) { closesocket(sconnection); delete response_buf; response_buf = NULL; return FALSE; } //发送Quit send(sconnection,_T("QUIT\r\n"),strlen(_T("QUIT\r\n")),0); if(!GetResponse(QUIT_SUCCESS)) { closesocket(sconnection); delete response_buf; response_buf = NULL; return FALSE; } return TRUE; }
把上一篇博客的base64编解码程序添加进来。
运行程序之后,QQ立马收到了邮件提示~~~