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

问题描述:

我想使用我的Gmail帐户通过C/C++程序发送电子邮件。我找到了一些资源,但是他们是用于LINUX的,并没有为我工作。我想在Windows上做这个。任何示例程序或建议,我将如何做到这一点将不胜感激。使用Gmail帐户通过C++发送电子邮件

感谢

#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 [email protected] [email protected] 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: <[email protected]> 
    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: <[email protected]> 
    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。因为谷歌邮件使用不同的技术。 Link TLS SSL,

+3

如果你的意思是“C或C++”,你应该说,而不是“C/C++”。 “C/C++”是一个敏感的话题。 – Steve314

+0

把代码没有为你工作,也许它可以纠正? – Ulterior

我需要一个支持安全连接的库(GNUTLS)。在建立安全连接后,我们可以交换身份验证数据,一旦我们接受了服务器,我们就可以使用我们的gmail凭证发送电子邮件。希望这将有助于其他面临类似问题。感谢您的好评。

+1

在答案中添加一个问题,然后将其标记为线程答案不是正确的方法。你应该更新了你的问题或者问了第二个问题。 – Offirmo

您需要一个实现SMTP的库。对于C++,我建议你看看VMime,虽然我不完全确定它是否支持Windows(有关于MingW编译的章节,所以我想有Winsock的本地支持)。对于C++,我建议你看一下VMime

或者,C库libcurl可以处理许多协议,包括SMTP。

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