在Windows错误检查中使用C++发送电子邮件到Gmail帐户

在Windows错误检查中使用C++发送电子邮件到Gmail帐户,c++,sockets,email,visual-c++,C++,Sockets,Email,Visual C++,我知道这已经被很多人讨论过了,但我不是问怎么做,我只是问为什么它不起作用。我做错了什么。上面说邮件发送成功,但我在收件箱里没有看到。我想向gmail帐户发送电子邮件,而不是通过它 #include <iostream> #include <windows.h> #include <fstream> #include <conio.h> #pragma comment(lib, "ws2_32.lib") // Insist on at least

我知道这已经被很多人讨论过了,但我不是问怎么做,我只是问为什么它不起作用。我做错了什么。上面说邮件发送成功,但我在收件箱里没有看到。我想向gmail帐户发送电子邮件,而不是通过它

#include <iostream>
#include <windows.h>
#include <fstream>
#include <conio.h>
#pragma comment(lib, "ws2_32.lib")

// Insist on at least Winsock v1.1
const int VERSION_MAJOR = 1;
const int VERSION_MINOR = 1;

#define CRLF "\r\n"                 // carriage-return/line feed pair
using namespace std;

// Basic error checking for send() and recv() functions
void Check(int iStatus, char *szFunction)
{
  if((iStatus != SOCKET_ERROR) && (iStatus))
    return;

  cerr<< "Error during call to " << szFunction << ": " << iStatus << " - " << GetLastError() << endl;
}

int main(int argc, char *argv[])
{
  int         iProtocolPort        = 25;
  char        szSmtpServerName[64] = "";
  char        szToAddr[64]         = "";
  char        szFromAddr[64]       = "";
  char        szBuffer[4096]       = "";
  char        szLine[255]          = "";
  char        szMsgLine[255]       = "";
  SOCKET      hServer;
  WSADATA     WSData;
  LPHOSTENT   lpHostEntry;
  LPSERVENT   lpServEntry;
  SOCKADDR_IN SockAddr;

  // Check for four command-line args
  //if(argc != 5)
   // ShowUsage();

  // Load command-line args
  lstrcpy(szSmtpServerName, "smtp.gmail.com");
  lstrcpy(szToAddr, "xxxx@gmail.com");
  lstrcpy(szFromAddr, "xxx@gmail.com");

  // Create input stream for reading email message file
  ifstream MsgFile("D:\\d.txt");

  // Attempt to intialize WinSock (1.1 or later)
  if(WSAStartup(MAKEWORD(VERSION_MAJOR, VERSION_MINOR), &WSData))
  {
    cout << "Cannot find Winsock v" << VERSION_MAJOR << "." << VERSION_MINOR << " or later!" << endl;

    return 1;
  }

  // Lookup email server's IP address.
  lpHostEntry = gethostbyname(szSmtpServerName);
  if(!lpHostEntry)
  {
    cout << "Cannot find SMTP mail server " << szSmtpServerName << endl;

    return 1;
  }

  // Create a TCP/IP socket, no specific protocol
  hServer = socket(PF_INET, SOCK_STREAM, 0);
  if(hServer == INVALID_SOCKET)
  {
    cout << "Cannot open mail server socket" << endl;

    return 1;
  }

  // Get the mail service port
  lpServEntry = getservbyname("mail", 0);

  // Use the SMTP default port if no other port is specified
  if(!lpServEntry)
    iProtocolPort = htons(IPPORT_SMTP);
  else
    iProtocolPort = lpServEntry->s_port;

  // Setup a Socket Address structure
  SockAddr.sin_family = AF_INET;
  SockAddr.sin_port   = iProtocolPort;
  SockAddr.sin_addr   = *((LPIN_ADDR)*lpHostEntry->h_addr_list);

  // Connect the Socket
  if(connect(hServer, (PSOCKADDR) &SockAddr, sizeof(SockAddr)))
  {
    cout << "Error connecting to Server socket" << endl;

    return 1;
  }

  // Receive initial response from SMTP server
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() Reply");

  // Send HELO server.com
  sprintf(szMsgLine, "HELO %s%s", szSmtpServerName, CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() HELO");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() HELO");

  // Send MAIL FROM: <sender@mydomain.com>
  sprintf(szMsgLine, "MAIL FROM:<%s>%s", szFromAddr, CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() MAIL FROM");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() MAIL FROM");

  // Send RCPT TO: <receiver@domain.com>
  sprintf(szMsgLine, "RCPT TO:<%s>%s", szToAddr, CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() RCPT TO");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() RCPT TO");

  // Send DATA
  sprintf(szMsgLine, "DATA%s", CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() DATA");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() DATA");
  //strat writing about the subject, end it with two CRLF chars and after that you can 
  //write data to the body oif the message
  sprintf(szMsgLine, "Subject: My own subject %s%s", CRLF, CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() DATA");




  // Send all lines of message body (using supplied text file)
  MsgFile.getline(szLine, sizeof(szLine));             // Get first line

  do         // for each line of message text...
  {
    sprintf(szMsgLine, "%s%s", szLine, CRLF);
    Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() message-line");
    MsgFile.getline(szLine, sizeof(szLine)); // get next line.
  } while(!MsgFile.eof());

  // Send blank line and a period
  sprintf(szMsgLine, "%s.%s", CRLF, CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() end-message");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() end-message");

  // Send QUIT
  sprintf(szMsgLine, "QUIT%s", CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() QUIT");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() QUIT");

  // Report message has been sent
  cout<< "Sent " << argv[4] << " as email message to " << szToAddr << endl;

  // Close server socket and prepare to exit.
  closesocket(hServer);

  WSACleanup();
  _getch();
  return 0;
}

Google Mail SMTP服务器将不接受任何未经身份验证的邮件。如果发件人不是GMail用户,您可能会成功,并且您可以使会话看起来像是从另一个邮件服务器到GMail用户邮箱的中继传递,但一旦您的发件人是@GMail.com,此选项就不可用

您必须进行身份验证,即启用SSL或TLS的会话端口465、587,然后进行密码身份验证。这样,邮件服务器将接受您的邮件。您可以使用来为您执行TLS/SSL


现在,当您有了这个代码片段时,您需要查看发送给您的响应。我确信您已经解释了身份验证是强制性的。

谷歌邮件SMTP服务器不会接受任何未经身份验证的邮件。如果发件人不是GMail用户,您可能会成功,并且您可以使会话看起来像是从另一个邮件服务器到GMail用户邮箱的中继传递,但一旦您的发件人是@GMail.com,此选项就不可用

您必须进行身份验证,即启用SSL或TLS的会话端口465、587,然后进行密码身份验证。这样,邮件服务器将接受您的邮件。您可以使用来为您执行TLS/SSL



现在,当您有了这个代码片段时,您需要查看发送给您的响应。我肯定你有一些东西解释了身份验证是强制性的。

我从互联网上获得了代码。可能是因为Gmail使用TLS吗?在发送任何内容之前,你需要向Gmail服务器进行身份验证。“发送”中的错误代码仅告诉您操作系统级错误、应用程序级错误,例如服务器回复中的身份验证错误。至少把它们打印出来看看发生了什么。我已经编辑了我的帖子,我想发送一封简单的电子邮件,就像联系方式中的邮件一样。。我不想用gmail作为载体。您的评论是否仍然适用于此?如果您使用不需要身份验证的SMTP服务器,而不是SMTP.gmail.com,您可能可以解决此问题。不过最好还是检查一下服务器的回复。我是从互联网上获得代码的。可能是因为Gmail使用TLS吗?在发送任何东西之前,你需要向Gmail服务器进行身份验证。“发送”中的错误代码仅告诉您操作系统级错误、应用程序级错误,例如服务器回复中的身份验证错误。至少把它们打印出来看看发生了什么。我已经编辑了我的帖子,我想发送一封简单的电子邮件,就像联系方式中的邮件一样。。我不想用gmail作为载体。您的评论是否仍然适用于此?如果您使用不需要身份验证的SMTP服务器,而不是SMTP.gmail.com,您可能可以解决此问题。不过最好还是检查服务器的回复。这也适用于雅虎吗?或者任何在SMTP服务器上使用TLS或SSL?密码保护的服务器都不是强制性的。然而,由于没有人希望通过自己的服务器转发垃圾邮件,所以很难找到一个完全开放的服务器来接收邮件。从雅虎SMTP的说法来看,它与谷歌差不多。在Windows中,只需使用一些工具或库就可以通过该安全且受密码保护的协议为您传递邮件。Hei发现lavabit smtp服务器邮件可以在没有身份验证的情况下工作,但根据我的代码,我会在邮件头中获取正文邮件。有什么想法吗?关于设置正文消息的大小?好的,我已经克服了这一点,我修改了代码,使其反映已解决的版本。这是否也适用于yahoo?或者任何在SMTP服务器上使用TLS或SSL?密码保护的服务器都不是强制性的。然而,由于没有人希望通过自己的服务器转发垃圾邮件,所以很难找到一个完全开放的服务器来接收邮件。从雅虎SMTP的说法来看,它与谷歌差不多。在Windows中,只需使用一些工具或库就可以通过该安全且受密码保护的协议为您传递邮件。Hei发现lavabit smtp服务器邮件可以在没有身份验证的情况下工作,但根据我的代码,我会在邮件头中获取正文邮件。有什么想法吗?关于设置正文消息的大小的一些事情?好的,我已经克服了这一点,我修改了代码,以便它反映已解决的版本。