zoukankan      html  css  js  c++  java
  • [计算机网络] 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
    ";
     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
    ";
     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
    ";
     70     //发送邮箱名lca1826@163.com的BASE64编码
     71     char bufferpsw[] = "bGNhMTgyNg==
    ";
     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>
    ";
     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>
    ";
     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
    ";
     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
    ";
    102     char bufferTo[] = "to:lca1826@sina.com
    ";
    103     char bufferSubject[] = "subject:hello from test
    ";
    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!!!
    ";
    114     cout<<"virus!!!"<<endl;
    115     send(s, buffersend, strlen(buffersend), 0);
    116 
    117     //end
    118     char bufferPoint[] = ".
    ";
    119     send(s, bufferPoint, strlen(bufferPoint), 0);
    120     response(s,bufferresv);
    121 
    122     //quit
    123     char bufferend[] = "quit
    ";
    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:该邮件包含未被网容易许可内容。违背网易反垃圾邮件条款

  • 相关阅读:
    零散杂记
    Result || IResult
    策略模式
    unity中的WWW通讯问题
    在webView 中使用JS 调用 Android / IOS的函数 Function
    不同云区域Proxy安装错误记录
    标准运维加载插件
    蓝鲸考试模拟
    PAAS组件迁移
    脚本安装halo
  • 原文地址:https://www.cnblogs.com/lca1826/p/6562016.html
Copyright © 2011-2022 走看看