使用C++通过Gmail帐户发送电子邮件

3
我想通过使用我的Gmail帐户在C/C++程序中发送电子邮件。我找到了一些资源,但它们是为Linux而设计的,并不能满足我的需求。我想在Windows上实现这个功能。如果有示例程序或建议,我将不胜感激。
谢谢
#define WIN32_LEAN_AND_MEAN

#include <stdio.h>
#include <stdlib.h>
#include <fstream.h>
#include <iostream.h>
#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;
}

但我认为这不适用于Gmail。因为Google Mail使用不同的技术。链接TLS SSL。


3
如果你的意思是“C或者C++”,那么最好这样说,而不是使用“C/C++”。 “C/C++”是一个敏感的话题。 - user180247
请把你遇到问题的代码贴出来,也许可以进行修正。 - Ulterior
3个回答

3

你需要一个实现SMTP的库。

对于C ++,我建议您查看VMime,尽管我不确定它是否支持Windows(有一个使用MingW编译的部分,因此我想象它具有本地Winsock支持)。

另外,C库libcurl处理许多协议,包括SMTP。


2

请查看基于libcurl的libquickmail (http://sourceforge.net/projects/libquickmail/),支持TLS,还可以发送附件并使用身份验证。这个库可以与MinGW编译,因此可以在Windows上使用。


0
我需要一个支持安全连接(GNUTLS)的库。在建立安全连接后,我们可以交换身份验证数据。一旦得到服务器的接受,我们就可以使用自己的gmail凭据发送电子邮件。希望这能帮助其他遇到类似问题的人。感谢你们的回复。

4
在回答中添加问题,然后将其标记为主题答案并不是正确的方法。你应该更新你的问题或者提出第二个问题。 - Offirmo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接