【问题标题】:Send email through Gmail using c++, Linux使用 C++、Linux 通过 Gmail 发送电子邮件
【发布时间】:2011-08-22 17:57:50
【问题描述】:

我想使用 C++ 通过 Gmail 发送电子邮件,因为我会从配置为使用 Gmail 帐户的桌面邮件客户端发送电子邮件。

我一直在研究 jwSMTP 和 popen+sendmail 之类的一些,但它们看起来只有在主机是邮件服务器时才有效。我知道这个任务在 Python 中是一条很好的路径,但从未在 C++ 中尝试过。

帮助表示赞赏! (c:

【问题讨论】:

  • jwSMTP 看起来应该适用于任何目标 SMTP 服务器...

标签: c++ email client gmail


【解决方案1】:

您将通过 gmail 的 smtp 服务器 (smtp.gmail.com) 发送邮件。客户端需要支持 SSL 或 TLS 才能连接。

它们都支持 SSL/TLS,应该可以很好地与 gmail 配合使用。使用 gmail 发送出站邮件的设置为:

Outgoing Mail (SMTP) Server (requires TLS or SSL): smtp.gmail.com
Use Authentication: Yes
Port for TLS/STARTTLS: 587
Port for SSL: 465
Account Name:  your full email address (including @gmail.com or @your_domain.com)
Email Address:  your email address (username@gmail.com or username@your_domain.com)
Password: your Gmail password

http://mail.google.com/support/bin/answer.py?hl=en&answer=13287

【讨论】:

    【解决方案2】:
    #include <windows.h>
    #include <winsock2.h>
    
    #pragma comment(lib, "ws2_32.lib")
    
    // Insist on at least Winsock v1.1
    const VERSION_MAJOR = 1;
    const VERSION_MINOR = 1;
    
    #define CRLF "\r\n"                 // carriage-return/line feed pair
    
    void ShowUsage(void)
    {
      cout << "Usage: SENDMAIL mailserv to_addr from_addr messagefile" << endl
           << "Example: SENDMAIL smtp.myisp.com rcvr@elsewhere.com my_id@mydomain.com message.txt" << endl;
    
      exit(1);
    }
    
    // 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        = 0;
      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, argv[1]);
      lstrcpy(szToAddr, argv[2]);
      lstrcpy(szFromAddr, argv[3]);
    
      // Create input stream for reading email message file
      ifstream MsgFile(argv[4]);
    
      // 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");
    
      // 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.good());
    
      // 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();
    
      return 0;
    }
    

    【讨论】:

      【解决方案3】:

      基本上任何在 linux 上可用的像样的 SMTP 库都可以完成这项工作,例如POCO 提供SMTPClientSession

      【讨论】:

      • libesmtp 真的有效吗?有人试过吗?我编译了 esmtp 提供的示例程序,并尝试在我的 gmail 帐户上发送电子邮件。没有报告错误,但 gmail 不显示新电子邮件。
      猜你喜欢
      • 2015-06-10
      • 1970-01-01
      • 2012-01-07
      • 2023-03-19
      • 1970-01-01
      • 2011-06-08
      相关资源
      最近更新 更多