C++SMTP服务器

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

img

基于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服务器要求的内容格式,设置好邮件内容的编码方式、分隔符、标头等信息;
错误处理:在代码中添加合适的错误处理逻辑,以便及时发现和解决任何异常情况。
希望这些信息能够帮助到你,快速解决当前遇到的问题。

根据您提供的信息,您遇到了一个503错误:“需要先使用EHLO和AUTH!”。这个错误通常会发生在发送电子邮件时,其中有一些步骤或设置出现问题。

为了更好地理解和解决这个问题,我需要更多的信息。以下是建议的排除步骤:

  1. 检查您的SMTP(Simple Mail Transfer Protocol)设置是否正确。确保您的SMTP服务器的主机名、端口号、加密等设置都正确。可以通过网上搜索相关的SMTP服务器设置来找到正确的设置方法。
  2. 检查您的电子邮件客户端的设置是否正确。如果您使用的是第三方电子邮件客户端,如Outlook、Thunderbird等,请确保您已正确设置SMTP服务器信息,包括账户名、密码等信息。
  3. 检查您的邮件内容和格式是否正确。在发送电子邮件时,请确保您的邮件内容符合规范,并且不包含任何可能会导致电子邮件被视为垃圾邮件的内容。例如,过多的垃圾邮件字眼、大量收件人等都可能导致电子邮件被拒绝或标记为垃圾邮件。
  4. 检查您的网络连接是否正常。如果您的网络连接不稳定或中断,可能会导致电子邮件无法发送或接收。请检查您的网络连接是否正常,并尝试重新发送电子邮件。

希望以上建议可以帮助您解决问题。如果问题仍然存在,请提供更多信息和具体情况,以便我更好地为您提供帮助。

你的邮箱需要设置安全码,不是直接用账户和密码就能够通信的,可以参考我的java实战文章,作为参考
https://blog.csdn.net/xishining/article/details/124138128
授权码获取方式:https://www.cnblogs.com/yinzhengjie2020/p/12355157.html