C++ 使用winsock(cpp)发送电子邮件时出现问题

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

为什么我的电子邮件不想发送?我尝试在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 '^]'.
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()