[计算机网络] C++模拟telnet登陆SMTP服务发送邮件过程
在百度文庫中的《使用telnet協議收發郵件》,我們可以很清楚地看到如何通過telnet來進行發送郵件,下面是一些需要用到的命令,通過以下命令可以很容易實現郵件發送功能。為了更好地理解其中每一步的含義,我決定自己寫一份可以自動發送郵件的代碼。
1 #include <winsock.h> 2 #include <stdio.h> 3 #include <string> 4 #include <iostream> 5 using namespace std; 6 #define WSWENS MAKEWORD(2,0) 7 #define MAXLINE 10240 8 9 //將服務器回應的信息打印 10 void response(SOCKET sock,char buff[]) 11 { 12 int len = recv(sock, buff, MAXLINE, 0); 13 buff[len]=0; 14 cout<<buff<<endl; 15 } 16 17 int main() 18 { 19 sockaddr_in sin; 20 WSADATA wsadata; 21 22 //對Winsock服務初始化 23 if(WSAStartup(WSWENS, &wsadata) !=0) 24 cout<<"startup failed"<<endl; 25 26 //創建套接字,指定端口號 27 SOCKET s = socket(PF_INET,SOCK_STREAM,0); 28 memset(&sin, 0, sizeof(sin)); 29 sin.sin_family = AF_INET; 30 sin.sin_port = htons(25); 31 32 //獲取服務器IP地址 33 hostent* hptr = gethostbyname("smtp.163.com"); 34 memcpy(&sin.sin_addr.S_un.S_addr, hptr->h_addr_list[0], hptr->h_length); 35 printf("IP of smpt.163.com is : %d:%d:%d:%d", 36 sin.sin_addr.S_un.S_un_b.s_b1, 37 sin.sin_addr.S_un.S_un_b.s_b2, 38 sin.sin_addr.S_un.S_un_b.s_b3, 39 sin.sin_addr.S_un.S_un_b.s_b4); 40 cout << endl; 41 42 //建立與服務器的連接 43 if(connect(s, (sockaddr*)&sin, sizeof(sin))) 44 { 45 cout << "connect failed!" << endl; 46 exit(0); 47 } 48 else 49 { 50 cout << "connect success!" << endl; 51 } 52 53 char bufferresv[10240]; 54 response(s, bufferresv); 55 56 // send "ehlo" 57 char bufferHello[] = "ehlo lca\r\n"; 58 cout << "ehlo..." << endl; 59 send(s, bufferHello, strlen(bufferHello), 0); 60 response(s,bufferresv); 61 62 // send "auth login" 63 char bufferLogin[] = "auth login\r\n"; 64 cout << "auth login..." << endl; 65 send(s, bufferLogin, strlen(bufferLogin),0); 66 response(s,bufferresv); 67 68 // send "username", "psw" 69 char bufferUserName[] = "bGNhMTgyNkAxNjMuY29t\r\n"; 70 //發送郵箱名lca1826@163.com的BASE64編碼 71 char bufferpsw[] = "bGNhMTgyNg==\r\n"; 72 //發送郵箱密碼lca182600的BASE64編碼 73 74 cout << "input username...." << endl; 75 send(s,bufferUserName,strlen(bufferUserName),0); 76 response(s,bufferresv); 77 78 cout << "input password..." << endl; 79 send(s,bufferpsw,strlen(bufferpsw),0); 80 response(s,bufferresv); 81 82 // mail from:<lca1826@163.com> 83 char bufferMailFrom[] = "mail from:<lca1826@163.com>\r\n"; 84 cout << "mail from:<lca1826@163.com>..." << endl; 85 send(s, bufferMailFrom, strlen(bufferMailFrom), 0); 86 response(s,bufferresv); 87 88 // rcpt to:<lca1826@sina.com> 89 char bufferRcptTo[] = "rcpt to:<lca1826@sina.com>\r\n"; 90 cout << "rcpt to:<lca1826@sina.com>..." << endl; 91 send(s, bufferRcptTo, strlen(bufferRcptTo), 0); 92 response(s,bufferresv); 93 94 // data 95 char bufferData[] = "data\r\n"; 96 cout << "data..." << endl; 97 send(s, bufferData,strlen(bufferData), 0); 98 response(s,bufferresv); 99 100 // from.. to.. subject.. 101 char bufferFrom[] = "from:lca1826@163.com\r\n"; 102 char bufferTo[] = "to:lca1826@sina.com\r\n"; 103 char bufferSubject[] = "subject:hello from test\r\n"; 104 105 cout << "from:lca1826@163.com..." << endl; 106 send(s, bufferFrom, strlen(bufferFrom), 0); 107 cout << "to:lca1826@sina.com... " << endl; 108 send(s, bufferTo, strlen(bufferTo), 0); 109 cout << "subject:hello from test..." << endl; 110 send(s, bufferSubject, strlen(bufferSubject), 0); 111 112 //content 113 char buffersend[] = "virus!!!\r\n"; 114 cout<<"virus!!!"<<endl; 115 send(s, buffersend, strlen(buffersend), 0); 116 117 //end 118 char bufferPoint[] = ".\r\n"; 119 send(s, bufferPoint, strlen(bufferPoint), 0); 120 response(s,bufferresv); 121 122 //quit 123 char bufferend[] = "quit\r\n"; 124 send(s, bufferend, strlen(bufferend), 0); 125 response(s,bufferresv); 126 return 0; 127 }
下面是程序運行后的截圖:
下面是發送成功后的截圖:
注:在上述編碼的時候需要使用BASE64加密解密,可使用這個網站http://tool.chinaz.com/Tools/base64.aspx
總結:
1.在用QQ郵箱做服務器很不穩定,有時候根本就連不上服務器,有時候在輸入auth login會返回錯誤,尤其是在用BASE64編碼后的用戶名和密碼輸入時永遠返回530錯誤,即使已經在QQ郵箱中設置了SMTP服務,并且用授權碼登陸,依舊失敗,這個問題一直找不到解決辦法,于是換成163郵箱做服務器。
2.通過各種調試,幾乎遇到了下列的所有錯誤,不過最終大部分都解決了,有些錯誤可能只是因為服務器太忙,多嘗試幾次就好了,只有一個554錯誤(下圖),在發送郵件是會被當作垃圾郵件攔截,而且在還沒有發送成功時就發生這個錯誤,可見并不是因為發送過多或者過于頻繁導致的發送失敗,雖然等了一段時間再運行程序會發送成功,但這個問題也還沒有找到解決辦法。
telnet發送郵件過程中返回的各種信息:
220 :服務就緒(通常知名服務器類型)
250 :請求郵件動作正確,完成(HELO,MAIL FROM,RCPT TO,QUIT 指令執行成功會返回此信息)
235 :認證通過
221 :正在處理
334 :在加密后的用戶名和密碼輸入后返回此信息
354 :開始發送數據,以 .結束(DATA指令執行成功會返回此信息)
500 :語法錯誤,命令不能識別
530 :未設置SMTP服務
550 :命令不能執行,郵箱無
554 DT:SPM:該郵件包含未被網容易許可內容。違背網易反垃圾郵件條款
?
轉載于:https://www.cnblogs.com/lca1826/p/6562016.html
總結
以上是生活随笔為你收集整理的[计算机网络] C++模拟telnet登陆SMTP服务发送邮件过程的全部內容,希望文章能夠幫你解決所遇到的問題。