[计算机网络] 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     //发送邮箱名[email protected]的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:<[email protected]>
 83     char bufferMailFrom[] = "mail from:<[email protected]>\r\n";
 84     cout << "mail from:<[email protected]>..." << endl;
 85     send(s, bufferMailFrom, strlen(bufferMailFrom), 0);
 86     response(s,bufferresv);
 87
 88     // rcpt to:<[email protected]>
 89     char bufferRcptTo[] = "rcpt to:<[email protected]>\r\n";
 90     cout << "rcpt to:<[email protected]>..." << 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:[email protected]\r\n";
102     char bufferTo[] = "to:[email protected]\r\n";
103     char bufferSubject[] = "subject:hello from test\r\n";
104
105     cout << "from:[email protected]" << endl;
106     send(s, bufferFrom, strlen(bufferFrom), 0);
107     cout << "to:[email protected] " << 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:该邮件包含未被网容易许可内容。违背网易反垃圾邮件条款

时间: 03-16

[计算机网络] C++模拟telnet登陆SMTP服务发送邮件过程的相关文章

使用telnet登陆smtp服务发邮件

最近在弄公司的反垃圾邮件系统,发现有个邮件系统发了不少的垃圾邮件进来,使用telnet 登录上去,尝试发一下邮件,竟然能成功发送,原来这邮局系统是没有限制,被利用了,唉,下面介绍一下如何使用命令 telnet 来进行伪造手工发送邮件. # telnet mail.coratur.cu 25 helo coratur.cu mail from:<[email protected]> rcpt to:<[email protected]> data from:[email protec

Nagios监控之利用sendmail使用第三方SMTP服务发送邮件报警

使用Centos系统自带的sendmail服务作为客户端,使用第三方SMTP服务发送邮件报警. 此功能是在nagios服务正常安装运行的基础上实现的;因此要先安装好基本的nagios运行环境,这个可以参考本人相关的博文. 1.软件检测及安装 #rpm -q sendmail 不存在怎安装 #yum -y install sendmail 2.停止sendmail服务 这里不需要sendmail作为邮件服务端来运行,所以关闭sendmail服务. #service sendmail stop 3.

Linux SendMail 使用外部SMTP服务发送邮件

前言 现在sendmail服务是Linux系统自带服务,默认可能没有启动. 本文不是讲解如何搭建本地mail服务器,而仅仅是作为客户端,使用外部smtp服务发送邮件,因此无需启动sendmail服务. 学习笔记,以备查阅. 1.Sendmail配置 配置发生邮件的邮箱认证信息 vi /etc/mail.rc --- 增加如下内容 --- 1 set [email protected] 2 set smtp=mail.your-domain.com 3 set smtp-auth-user=you

通过telnet使用smtp协议发送邮件

smtp协议是一个简单的邮件传输协议,利用它我们可以将邮件发送给别人,这里将通过telnet这个程序利用smtp协议从网易向gmail发送一封邮件 网上不少有说使用telnet发送邮件的文章,我也看过了,多数的步骤是这样的 1.使用telnet连接smtp服务器2.发送一个helo或者ehlo指令3.验证用户(使用邮件名登陆)4.使用mail命令准备发送邮件5.使用rcpt命令指定对方邮箱地址6.使用data命令开始输入内容7.输入test或者hello world类似字样(即邮件内容)8.输入

推荐使用SMTP服务发送邮件

通配置web.config发送邮件,(服务器上也能成功,推荐这种方式,方便以后修改smtp服务) userName是你的邮箱地址,password是你的授权码 配置文件如下 <configuration> <system.net> <mailSettings> <smtp deliveryMethod="Network" from="[email protected]" > <network host="

php使用smtp服务发送邮件 第一

define('SMTP_STATUS_NOT_CONNECTED', 1, true); define('SMTP_STATUS_CONNECTED', 2, true); class smtp { var $connection; var $recipients; var $headers; var $timeout; var $errors; var $status; var $body; var $from; var $host; var $port; var $helo; var $a

php使用smtp服务发送邮件 第二

$jieguo=$smtp->sendmail($smtpemailto, $smtpusermail, $mailsubject, $mailbody, $mailtype); $smtpserver = "smtp.exmail.qq.com";//SMTP服务器 $smtpserverport =25;//SMTP服务器端口 $smtpusermail = "用户邮箱";//SMTP服务器的用户邮箱 $smtpemailto = "发送给谁&q

php使用smtp服务发送邮件 第三开启QQ邮箱开启SMTP服务的步骤

1 2 3 分步阅读 首先要确保你的QQ邮箱已经要开启超过一个月.对于新开启的邮箱,腾讯是不开放这些功能的. 方法/步骤 首先点QQ头像旁边的信封符号进入邮箱. 当然你也可以使用 mail.qq.com进邮箱 进入邮箱后点击顶部的设置按钮 点击二级目录"账户" 拉到中下部 把这两项勾上 QQ邮箱 POP3 和 SMTP 服务器地址设置如下:邮箱POP3服务器(端口110)SMTP服务器(端口25)qq.compop.qq.comsmtp.qq.comSMTP服务器需要身份验证. 如果是

设置Linux使用SMTP服务发送邮件

很多时候我们需要知道服务器的运行状态,比如发生了异常的报警.数据库备份的状态等,假如服务器自动跟你汇报那就好了,我们可以通过设置当触发某些条件时让服务器发送邮件给你,这样你就可以了解你的服务器的状态怎么样.一开始我使用linux本身的mail测试发送邮件,结果系统是提示发送出去了,但是测试接收邮箱没有接收到邮件,转而使用第三方邮箱来作为发送方,下面是设置163邮箱作为发送邮箱的过程. 一.进入/etc/mail.rc编辑模式添加以下两行配置 注意这个smtp-auth-password并不是邮箱