C++ 使用winsock(cpp)发送电子邮件时出现问题
为什么我的电子邮件不想发送?我尝试在telnet和电子邮件中发送命令。 我试图打印服务器的输出,并给了我C++ 使用winsock(cpp)发送电子邮件时出现问题,c++,smtp,winsock2,C++,Smtp,Winsock2,为什么我的电子邮件不想发送?我尝试在telnet和电子邮件中发送命令。 我试图打印服务器的输出,并给了我 235 Authentication succeeded 问题是我想到了“来自piotrek的邮件”。m@mail.com" 从控制台输出 lsd@DESKTOP-U4D23JB:~$ telnet smtp.mail.com 587 Trying 74.208.5.15... Connected to smtp.mail.com. Escape character is '^]'. 22
235 Authentication succeeded
问题是我想到了“来自piotrek的邮件”。m@mail.com"
从控制台输出
lsd@DESKTOP-U4D23JB:~$ telnet smtp.mail.com 587
Trying 74.208.5.15...
Connected to smtp.mail.com.
Escape character is '^]'.
220 gmx.com (mrgmxus004) Nemesis ESMTP Service ready
EHLO t
250-gmx.com Hello t [79.187.142.70]
250-8BITMIME
250-AUTH LOGIN PLAIN
250-SIZE 141557760
250 STARTTLS
AUTH LOGIN
334 VXNlcm5hbWU6
(my base64 login)
334 UGFzc3dvcmQ6
(my base64 pass)
235 Authentication succeeded
MAIL FROM: piotrek.m@mail.com
250 Requested mail action okay, completed
RCPT TO: piotrek.m@mail.com
250 OK
DATA
354 Start mail input; end with <CRLF>.<CRLF>
FROM: piotrek.m@mail.com
TO: piotrek.m@mail.com
SUBJECT: asdfasfdssf
asdasdasdasdasdasd
.
250 Requested mail action okay, completed: id=0MDiX2-1kTprK3nZO-00HAti
#pragma warning(disable:4996)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <WinSock2.h>
#define SMTP_HOST "smtp.mail.com"
#define SMTP_PORT 587
unsigned const char SMTP_USERNAME[] = "examplm@mail.com";
unsigned const char SMTP_PASSWORD[] = "supersecretpassword@";
static int sendmail(const char* from, const char* to, const char* subject, const char* body);
static void sendmail_write(const int sock, const char* str, const char* arg);
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len);
int main() {
char to[] = "piotrek.m@mail.com";
char* from = to;
sendmail(from, to, "subject123", "body1234");
}
static void sendmail_write(const int sock, const char* str, const char* arg) {
char buf[4096];
if (arg != NULL)
snprintf(buf, sizeof(buf), str, arg);
else
snprintf(buf, sizeof(buf), str);
send(sock, buf, strlen(buf), 0);
}
static int sendmail(const char* from, const char* to, const char* subject, const char* body) {
sockaddr_in service;
WSADATA wsaData;
SOCKET sock;
struct hostent* remoteHost;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != NO_ERROR) {
std::cout << 1;
return -1;
}
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
WSACleanup();
return -2;
}
remoteHost = gethostbyname(SMTP_HOST);
memset(&service, 0, sizeof(service));
service.sin_family = AF_INET;
service.sin_addr.s_addr = *(u_long*)remoteHost->h_addr_list[0];
service.sin_port = htons(SMTP_PORT);
if (connect(sock, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR) {
WSACleanup();
return EXIT_FAILURE;
}
std::string u_b64 = base64_encode(SMTP_USERNAME, strlen((char*)SMTP_USERNAME)) + "\r\n";
std::string p_b64 = base64_encode(SMTP_PASSWORD, strlen((char*)SMTP_PASSWORD)) + "\r\n";
sendmail_write(sock, "EHLO %s\r\n", from);
sendmail_write(sock, "AUTH LOGIN\r\n", NULL);
sendmail_write(sock, u_b64.c_str(), NULL);
sendmail_write(sock, p_b64.c_str(), NULL);
sendmail_write(sock, "DATA\n", NULL);
sendmail_write(sock, "MAIL FROM: %s\n", from);
sendmail_write(sock, "RCPT TO: %s\n", to);
sendmail_write(sock, "From: %s\n", from);
sendmail_write(sock, "To: %s\n", to);
sendmail_write(sock, "Subject: %s\n", subject);
sendmail_write(sock, "\n", NULL);
sendmail_write(sock, "%s\n", body);
sendmail_write(sock, ".\n", NULL);
sendmail_write(sock, "QUIT\n", NULL);
closesocket(sock);
return EXIT_SUCCESS;
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
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 += base64_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 += base64_chars[char_array_4[j]];
while ((i++ < 3))
ret += '=';
}
return ret;
}
lsd@DESKTOP-U4D23JB:~$telnet smtp.mail.com 587
正在尝试74.208.5.15。。。
已连接到smtp.mail.com。
转义字符为“^]”。
220 gmx.com(mrgmxus004)Nemesis ESMTP服务就绪
埃洛t
250-gmx.com你好t[79.187.142.70]
250-8比特
250-AUTH普通登录
250号141557760
250标准
身份验证登录
334 VXNlcm5hbWU6
(我的base64登录)
334 UGFzc3dvcmQ6
(我的base64通行证)
235身份验证成功
邮寄地址:piotrek。m@mail.com
250请求的邮件操作正常,已完成
RCPT收件人:piotrek。m@mail.com
250行
资料
354开始邮件输入;以…结束。
发件人:piotrek。m@mail.com
致:piotrek。m@mail.com
主题:asdfasfdssf
asdasdasdasdasd
.
250请求的邮件操作正常,已完成:id=0MDiX2-1kTprK3nZO-00HAti
然后邮件已成功传递,但来自cpp代码的邮件未成功传递
代码
lsd@DESKTOP-U4D23JB:~$ telnet smtp.mail.com 587
Trying 74.208.5.15...
Connected to smtp.mail.com.
Escape character is '^]'.
220 gmx.com (mrgmxus004) Nemesis ESMTP Service ready
EHLO t
250-gmx.com Hello t [79.187.142.70]
250-8BITMIME
250-AUTH LOGIN PLAIN
250-SIZE 141557760
250 STARTTLS
AUTH LOGIN
334 VXNlcm5hbWU6
(my base64 login)
334 UGFzc3dvcmQ6
(my base64 pass)
235 Authentication succeeded
MAIL FROM: piotrek.m@mail.com
250 Requested mail action okay, completed
RCPT TO: piotrek.m@mail.com
250 OK
DATA
354 Start mail input; end with <CRLF>.<CRLF>
FROM: piotrek.m@mail.com
TO: piotrek.m@mail.com
SUBJECT: asdfasfdssf
asdasdasdasdasdasd
.
250 Requested mail action okay, completed: id=0MDiX2-1kTprK3nZO-00HAti
#pragma warning(disable:4996)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <WinSock2.h>
#define SMTP_HOST "smtp.mail.com"
#define SMTP_PORT 587
unsigned const char SMTP_USERNAME[] = "examplm@mail.com";
unsigned const char SMTP_PASSWORD[] = "supersecretpassword@";
static int sendmail(const char* from, const char* to, const char* subject, const char* body);
static void sendmail_write(const int sock, const char* str, const char* arg);
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len);
int main() {
char to[] = "piotrek.m@mail.com";
char* from = to;
sendmail(from, to, "subject123", "body1234");
}
static void sendmail_write(const int sock, const char* str, const char* arg) {
char buf[4096];
if (arg != NULL)
snprintf(buf, sizeof(buf), str, arg);
else
snprintf(buf, sizeof(buf), str);
send(sock, buf, strlen(buf), 0);
}
static int sendmail(const char* from, const char* to, const char* subject, const char* body) {
sockaddr_in service;
WSADATA wsaData;
SOCKET sock;
struct hostent* remoteHost;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != NO_ERROR) {
std::cout << 1;
return -1;
}
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
WSACleanup();
return -2;
}
remoteHost = gethostbyname(SMTP_HOST);
memset(&service, 0, sizeof(service));
service.sin_family = AF_INET;
service.sin_addr.s_addr = *(u_long*)remoteHost->h_addr_list[0];
service.sin_port = htons(SMTP_PORT);
if (connect(sock, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR) {
WSACleanup();
return EXIT_FAILURE;
}
std::string u_b64 = base64_encode(SMTP_USERNAME, strlen((char*)SMTP_USERNAME)) + "\r\n";
std::string p_b64 = base64_encode(SMTP_PASSWORD, strlen((char*)SMTP_PASSWORD)) + "\r\n";
sendmail_write(sock, "EHLO %s\r\n", from);
sendmail_write(sock, "AUTH LOGIN\r\n", NULL);
sendmail_write(sock, u_b64.c_str(), NULL);
sendmail_write(sock, p_b64.c_str(), NULL);
sendmail_write(sock, "DATA\n", NULL);
sendmail_write(sock, "MAIL FROM: %s\n", from);
sendmail_write(sock, "RCPT TO: %s\n", to);
sendmail_write(sock, "From: %s\n", from);
sendmail_write(sock, "To: %s\n", to);
sendmail_write(sock, "Subject: %s\n", subject);
sendmail_write(sock, "\n", NULL);
sendmail_write(sock, "%s\n", body);
sendmail_write(sock, ".\n", NULL);
sendmail_write(sock, "QUIT\n", NULL);
closesocket(sock);
return EXIT_SUCCESS;
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
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 += base64_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 += base64_chars[char_array_4[j]];
while ((i++ < 3))
ret += '=';
}
return ret;
}
#杂注警告(禁用:4996)
#包括
#包括
#包括
#包括
#定义SMTP_主机“SMTP.mail.com”
#定义SMTP_端口587
未签名的常量字符SMTP_用户名[]=“examplm@mail.com";
unsigned const char SMTP_PASSWORD[]=“supersecretpassword@”;
静态int sendmail(const char*from,const char*to,const char*subject,const char*body);
静态void sendmail_write(const int sock、const char*str、const char*arg);
std::string base64_encode(无符号字符常量*bytes_to_encode,无符号整数in_len);
int main(){
字符到[]=”piotrek。m@mail.com";
char*from=to;
发送邮件(发件人、收件人、“主题123”、“正文1234”);
}
静态void sendmail_write(常量int sock、常量char*str、常量char*arg){
char-buf[4096];
如果(arg!=NULL)
snprintf(buf,sizeof(buf),str,arg);
其他的
snprintf(buf,sizeof(buf),str);
发送(sock、buf、strlen(buf)、0);
}
静态int sendmail(const char*from、const char*to、const char*subject、const char*body){
正在使用的sockaddr_;
WSADATA WSADATA;
插座;
结构主机*远程主机;
int result=WSAStartup(MAKEWORD(2,2)和wsaData);
如果(结果!=无错误){
std::cout h_addr_list[0];
service.sin_port=htons(SMTP_端口);
if(connect(sock,(SOCKADDR*)和service,sizeof(service))==SOCKET\u错误){
WSACleanup();
返回退出失败;
}
std::string u_b64=base64_编码(SMTP_用户名,strlen((char*)SMTP_用户名))+“\r\n”;
std::string p_b64=base64_编码(SMTP_密码,strlen((char*)SMTP_密码))+“\r\n”;
sendmail\u write(sock,“EHLO%s\r\n”,来自);
sendmail\u write(sock,“AUTH LOGIN\r\n”,NULL);
sendmail_write(sock,u_b64.c_str(),NULL);
sendmail_write(sock,p_b64.c_str(),NULL);
sendmail_write(sock,“数据\n”,NULL);
sendmail\u write(sock,“邮件发件人:%s\n”,发件人);
发送邮件(sock,“收件人:%s\n”,收件人);
sendmail_write(sock,“发件人:%s\n”,发件人);
发送邮件(sock,“收件人:%s\n”,收件人);
sendmail_write(sock,“主题:%s\n”,主题);
sendmail_write(sock,“\n”,NULL);
sendmail_write(sock,“%s\n”,正文);
sendmail_write(sock,“.\n”,NULL);
sendmail\u write(sock,“QUIT\n”,NULL);
插座;
返回退出成功;
}
std::string base64_encode(无符号字符常量*bytes_to_encode,无符号整数in_len){
静态常量std::字符串base64_字符=
“ABCDEFGHIJKLMNOPQRSTUVWXYZ”
“abcdefghijklmnopqrstuvwxyz”
"0123456789+/";
std::字符串ret;
int i=0;
int j=0;
无符号字符数组3[3];
无符号字符数组4[4];
而(在_len--){
字符数组3[i++]=*(字节到编码++);
如果(i==3){
char_数组_4[0]=(char_数组_3[0]&0xfc)>>2;
char_数组_4[1]=((char_数组_3[0]&0x03)>4);
char_数组_4[2]=((char_数组_3[1]&0x0f)>6);
char_数组_4[3]=char_数组_3[2]&0x3f;
对于(i=0;(i<4);i++)
ret+=base64_字符[char_数组_4[i];
i=0;
}
}
如果(i){
对于(j=i;j<3;j++)
字符数组_3[j]='\0';
char_数组_4[0]=(char_数组_3[0]&0xfc)>>2;
char_数组_4[1]=((char_数组_3[0]&0x03)>4);
char_数组_4[2]=((char_数组_3[1]&0x0f)>6);
char_数组_4[3]=char_数组_3[2]&0x3f;
对于(j=0;(j
为什么中途停止发送回车?说你需要发送数据
,它会一直读到看到
你也会在从和RCPT发送邮件之前发送数据。请遵循Postel的原则,确保你的发送通信遵循SMTP协议。你的意思是什么?我举了一个例子第一行在<代码> \r\n>代码>结束,然后切换到<>代码> \n>代码>。您可以考虑读取任何返回的数据来查看是否有任何线索。<代码>邮件:PIOTRAK。m@mail.com和RCPT TO:piotrek。m@mail.com
是语法无效的SMTP命令。此特定服务器接受格式错误的命令,但不必。请参阅RFC 2821,以了解邮件自
和RCPT至
的正确语法。此外,由于没有正确遵循SMTP规范,您正在发送命令,但没有读取任何响应(甚至连服务器的初始问候语都没有)。您不能忽略响应。如果服务器报告了错误,请停止发送新命令(而不是退出),并根据需要向用户报告问题。您也没有检查fa的gethostbyname()