longbingyin 2023-05-30 22:54 采纳率: 100%
浏览 36
已结题

C++SMTP服务器

想自己做一个邮件服务器,但是遇到了问题。
为什么这里,我跟它发的东西一样的还会报错 ”503 Error: need EHLO and AUTH first !“

img

  • 写回答

3条回答 默认 最新

  • 叶秋学长 全栈领域优质创作者 2023-05-31 00:33
    关注

    基于ChatGPT4与博主叶秋学长的回答,望采纳!!!有其他问题也可以询问我哦💕:
    错误信息提示需要先执行EHLO和AUTH命令,EHLO命令是SMTP客户端和服务器进行握手协商的第一步,而AUTH命令则是用于验证用户身份的命令。因此,你需要在发送邮件前先执行EHLO和AUTH命令,以便通过SMTP服务器的身份验证。

    以下是一个简单的C++实现示例(假设使用的是加密连接):

    #include <iostream>
    #include <string>
    #include <regex>
    
    #include <openssl/ssl.h>
    #include <openssl/err.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    
    using namespace std;
    
    #define MAX_BUF_SIZE 4096
    
    int main()
    {
        // 初始化 SSL 库
        SSL_library_init();
        SSL_load_error_strings();
    
        // 创建 TCP 套接字
        int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sockfd < 0) {
            cerr << "Error: create socket failed." << endl;
            return -1;
        }
    
        // 连接 SMTP 服务器
        sockaddr_in servAddr;
        memset(&servAddr, 0, sizeof(servAddr));
        servAddr.sin_family = AF_INET;
        servAddr.sin_port = htons(465);
        inet_pton(AF_INET, "smtp.server.com", &servAddr.sin_addr);
    
        if (connect(sockfd, (sockaddr*)&servAddr, sizeof(servAddr)) < 0) {
            cerr << "Error: connect server failed." << endl;
            return -1;
        }
    
        // 基于套接字创建 SSL 对象
        SSL_CTX* ctx = SSL_CTX_new(TLS_client_method());
        SSL* ssl = SSL_new(ctx);
        SSL_set_fd(ssl, sockfd);
    
        // 建立 SSL 连接
        if (SSL_connect(ssl) <= 0) {
            cerr << "Error: SSL connect failed." << endl;
            ERR_print_errors_fp(stderr);
            return -1;
        }
    
        // 接收服务器欢迎信息
        char recvBuf[MAX_BUF_SIZE];
        int recvLen = SSL_read(ssl, recvBuf, sizeof(recvBuf)-1);
        recvBuf[recvLen] = '\0';
        cout << recvBuf;
    
        // 发送 EHLO 命令
        SSL_write(ssl, "EHLO client\r\n", strlen("EHLO client\r\n"));
    
        // 接收服务器回复
        recvLen = SSL_read(ssl, recvBuf, sizeof(recvBuf)-1);
        recvBuf[recvLen] = '\0';
        cout << recvBuf;
    
        // 发送 AUTH 命令
        SSL_write(ssl, "AUTH LOGIN\r\n", strlen("AUTH LOGIN\r\n"));
    
        // 接收服务器回复
        recvLen = SSL_read(ssl, recvBuf, sizeof(recvBuf)-1);
        recvBuf[recvLen] = '\0';
        cout << recvBuf;
    
        // 输入用户名和密码(base64 编码)
        string username = "user@example.com";
        string password = "password";
        string username_base64 = base64_encode((const unsigned char*)(username.c_str()), username.size());
        string password_base64 = base64_encode((const unsigned char*)(password.c_str()), password.size());
    
        // 发送用户名和密码
        SSL_write(ssl, username_base64.c_str(), username_base64.size());
        SSL_write(ssl, "\r\n", strlen("\r\n"));
        SSL_write(ssl, password_base64.c_str(), password_base64.size());
        SSL_write(ssl, "\r\n", strlen("\r\n"));
    
        // 接收服务器回复
        recvLen = SSL_read(ssl, recvBuf, sizeof(recvBuf)-1);
        recvBuf[recvLen] = '\0';
        cout << recvBuf;
    
        // 发送 MAIL FROM 命令
        string mailFrom = "MAIL FROM:<user@example.com>\r\n";
        SSL_write(ssl, mailFrom.c_str(), mailFrom.size());
    
        // 接收服务器回复
        recvLen = SSL_read(ssl, recvBuf, sizeof(recvBuf)-1);
        recvBuf[recvLen] = '\0';
        cout << recvBuf;
    
        // 发送 RCPT TO 命令
        string rcptTo = "RCPT TO:<recipient@example.com>\r\n";
        SSL_write(ssl, rcptTo.c_str(), rcptTo.size());
    
        // 接收服务器回复
        recvLen = SSL_read(ssl, recvBuf, sizeof(recvBuf)-1);
    recvBuf[recvLen] = '\0';
    cout << recvBuf;
    
    // 发送 DATA 命令
    SSL_write(ssl, "DATA\r\n", strlen("DATA\r\n"));
    
    // 接收服务器回复
    recvLen = SSL_read(ssl, recvBuf, sizeof(recvBuf)-1);
    recvBuf[recvLen] = '\0';
    cout << recvBuf;
    
    // 发送邮件内容
    string mailContent = "From: user@example.com\r\n";
    mailContent += "To: recipient@example.com\r\n";
    mailContent += "Subject: test email\r\n\r\n";
    mailContent += "This is a test email.\r\n";
    
    SSL_write(ssl, mailContent.c_str(), mailContent.size());
    
    // 发送结束标志
    SSL_write(ssl, ".\r\n", strlen(".\r\n"));
    
    // 接收服务器回复
    recvLen = SSL_read(ssl, recvBuf, sizeof(recvBuf)-1);
    recvBuf[recvLen] = '\0';
    cout << recvBuf;
    
    // 发送 QUIT 命令
    SSL_write(ssl, "QUIT\r\n", strlen("QUIT\r\n"));
    
    // 关闭 SSL 连接和套接字
    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    close(sockfd);
    
    return 0;
    }
    
    

    在实际使用中,还需要根据不同的SMTP服务器和邮件协议进行相应的调整和优化,以确保能够发送成功。上述示例中使用了base64编码来对用户名和密码进行加密,需要注意的是,这种方式并不安全,因为base64编码只是简单地将原始数据转换成可显示的字符序列,并没有进行加密。如果要保证邮件的安全性,建议使用TLS/SSL等加密传输协议,或者使用SMTP认证等更加安全的身份验证方式。

    此外,在实际使用中,还需要注意以下几点:

    SMTP服务器配置:确保SMTP服务器地址、端口号等信息正确配置;
    发送者和接收者信息:在发送邮件之前,需要设置好邮件中的发件人、收件人、主题和正文等信息;
    内容格式:根据SMTP服务器要求的内容格式,设置好邮件内容的编码方式、分隔符、标头等信息;
    错误处理:在代码中添加合适的错误处理逻辑,以便及时发现和解决任何异常情况。
    希望这些信息能够帮助到你,快速解决当前遇到的问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 6月12日
  • 已采纳回答 6月4日
  • 创建了问题 5月30日

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀