精易论坛

标题: SMTP通信 简单邮件发送源码 [打印本页]

作者: z13228604287    时间: 2024-6-22 09:27
标题: SMTP通信 简单邮件发送源码
本帖最后由 z13228604287 于 2024-6-22 09:28 编辑

[C++] 纯文本查看 复制代码
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
typedef int socklen_t;
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
typedef int SOCKET;
#endif

class SMTPClient {
public:
    // 构造函数,初始化服务器地址和端口
    SMTPClient(const std::string& server, int port) : server(server), port(port) {
#ifdef _WIN32
        WSADATA wsaData;
        WSAStartup(MAKEWORD(2, 2), &wsaData); // 初始化Winsock
#endif
    }

    // 析构函数,清理Winsock
    ~SMTPClient() {
#ifdef _WIN32
        WSACleanup();
#endif
    }

    // 连接到SMTP服务器
    bool connectToServer() {
        struct addrinfo hints, * res;
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;

        int status = getaddrinfo(server.c_str(), std::to_string(port).c_str(), &hints, &res);
        if (status != 0) {
            std::cerr << "错误:无法解析主机名. " << gai_strerror(status) << std::endl;
            return false;
        }

        sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        if (sock == INVALID_SOCKET) {
            std::cerr << "错误:无法创建套接字." << std::endl;
            freeaddrinfo(res);
            return false;
        }

        // 连接到服务器
        if (::connect(sock, res->ai_addr, res->ai_addrlen) == SOCKET_ERROR) {
            std::cerr << "错误:无法连接到服务器." << std::endl;
            freeaddrinfo(res);
            return false;
        }

        freeaddrinfo(res);
        return true;
    }

    //// 发送邮件
    //void sendMail(const std::string& from, const std::vector<std::string>& to, const std::string& subject, const std::string& body) {
    //    std::string msg = "EHLO localhost\r\n"; // 向服务器发送EHLO命令
    //    send(msg);
    //    recv();

    //    msg = "MAIL FROM:<" + from + ">\r\n"; // 发送MAIL FROM命令
    //    send(msg);
    //    recv();

    //    for (const auto& recipient : to) {
    //        msg = "RCPT TO:<" + recipient + ">\r\n"; // 发送RCPT TO命令
    //        send(msg);
    //        recv();
    //    }

    //    msg = "DATA\r\n"; // 发送DATA命令
    //    send(msg);
    //    recv();

    //    // 组装邮件内容
    //    msg = "Subject: " + subject + "\r\n";
    //    msg += "To: ";
    //    for (const auto& recipient : to) {
    //        msg += recipient + ";";
    //    }
    //    msg += "\r\n";
    //    msg += "\r\n" + body + "\r\n.\r\n";
    //    send(msg);
    //    recv();

    //    msg = "QUIT\r\n"; // 发送QUIT命令
    //    send(msg);
    //    recv();
    //}

    // 发送邮件
    void sendMail(const std::string& from, const std::vector<std::string>& to, const std::string& subject, const std::string& body) {
        std::string msg = "EHLO localhost\r\n";
        send(msg);
        recv();

        msg = "MAIL FROM:<" + from + ">\r\n";
        send(msg);
        recv();

        for (const auto& recipient : to) {
            msg = "RCPT TO:<" + recipient + ">\r\n";
            send(msg);
            recv();
        }

        msg = "DATA\r\n";
        send(msg);
        recv();

        msg = "Subject: " + subject + "\r\n";
        msg += "To: ";
        for (const auto& recipient : to) {
            msg += recipient + ";";
        }
        msg += "\r\n";
        msg += "Content-Type: text/html; charset=GB2312\r\n";
        msg += "\r\n" + body + "\r\n.\r\n";
        send(msg);
        recv();

        msg = "QUIT\r\n";
        send(msg);
        recv();
    }




private:
    std::string server;
    int port;
    SOCKET sock;

    // 发送数据
    void send(const std::string& data) {
        ::send(sock, data.c_str(), data.length(), 0);
    }

    // 接收服务器响应
    void recv() {
        char buffer[1024];
        int len = ::recv(sock, buffer, sizeof(buffer) - 1, 0);
        if (len > 0) {
            buffer[len] = '\0';
            std::cout << buffer; // 打印服务器响应
        }
    }
};

int main() {
    SMTPClient client("***.***.com", 25); // 初始化SMTP客户Duan
    if (client.connectToServer()) { // 连接到服务器

        // HTML格式的邮件内容
        std::string body = R"(
        <html>
        <head>
            <title>Test Email</title>
        </head>
        <body>
            <h1>This is a Test Email</h1>
            <p>演示 <strong>HTML</strong> content.</p>
            <p style="color: red;">This is a red paragraph.</p>
        </body>
        </html>
        )";


        client.sendMail("zhikongzhongxin@*******.com", { "Yong.Han@******.com" }, "Test Email", body); // 发送邮件
    }
    return 0;
}



作者: year1970    时间: 2024-6-22 09:57
感谢分享
作者: aismy    时间: 2024-6-22 10:10
25端口一般只是本机玩玩,想放在服务器上,还得其他端口, 不知道是否支持其他端口呢?
作者: mqq521521    时间: 2024-6-22 10:36
666666666666666666
作者: ZJ3120    时间: 2024-6-22 14:16
666666666666666666
作者: 396384183    时间: 2024-6-22 14:31
感谢分享
作者: jtucar    时间: 2024-6-22 17:30
感谢分享,很给力!~
作者: bianyuan456    时间: 2024-6-22 18:59
已经顶贴,感谢您对论坛的支持!
作者: 2446789312    时间: 2024-6-22 19:15

作者: LLZWWY    时间: 2024-6-22 21:18
感谢大佬无私分享
作者: 396384183    时间: 2024-6-23 00:39
论坛有你更精彩
作者: 小虎来了    时间: 2024-6-23 10:23
感谢分享。
作者: 鸿运    时间: 2024-6-23 11:02
这个数用什么 ide 写的c++代码
作者: ZHuanR    时间: 2024-6-23 16:42
新技能已get√
作者: wh1234567    时间: 2024-6-24 10:35
感谢分享。。。。
作者: wh1234567    时间: 2024-6-25 09:39
测试看看,感谢了
作者: renhe2018    时间: 2024-6-25 11:11
值得试试
作者: 光影魔术    时间: 2024-6-25 13:04
感谢分享源码
作者: qzone2030    时间: 2024-8-22 09:48
值得阅读学习
作者: as3071    时间: 2024-8-30 21:23
感谢分享。




欢迎光临 精易论坛 (https://125.confly.eu.org/) Powered by Discuz! X3.4