【chatgpt3.5】轻量级邮件服务器

33次阅读

共计 6375 个字符,预计需要花费 16 分钟才能阅读完成。

#include <iostream>#include <string>#include <cstring>#include <fstream>#include <filesystem>#include <winsock2.h>#pragma comment(lib, "ws2_32.lib")#define MAKE_INT32(str) \\    (static_cast<uint32_t>(str[0]) << 24 | \\     static_cast<uint32_t>(str[1]) << 16 | \\     static_cast<uint32_t>(str[2]) << 8 | \\     static_cast<uint32_t>(str[3]))namespace fs = std::filesystem;const int BUFFER_SIZE = 4096;bool receiveCommand(SOCKET clientSocket, std::string& command) {    char buffer[BUFFER_SIZE];    int bytesRead = recv(clientSocket, buffer, BUFFER_SIZE – 1, 0);    if (bytesRead <= 0) {        return false;   }    buffer[bytesRead] = \’\\0\’;    command = buffer;    return true;}std::string parseSender(const std::string& command) {    std::size_t start = command.find(\'<\’);    std::size_t end = command.find(\’>\’, start);    if (start != std::string::npos && end != std::string::npos) {        return command.substr(start + 1, end – start – 1);    }    return "";}std::string parseRecipient(const std::string& command) {    std::size_t start = command.find(\'<\’);    std::size_t end = command.find(\’>\’, start);    if (start != std::string::npos && end != std::string::npos) {        return command.substr(start + 1, end – start – 1);    }    return "";}bool createFolder(const std::string& folderPath) {    try {        fs::create_directory(folderPath);        return true;    }    catch (const std::exception& e) {        std::cerr << "Failed to create folder: " << e.what() << std::endl;        return false;    }}void saveEmailToFile(const std::string& emailContent, const std::string& sender, const std::string& recipient) {    std::string folderPath = "email";  // 文件夹路径     // 检查文件夹是否存在     if (createFolder(folderPath)) {        std::cout << "Folder created successfully." << std::endl;   }     std::string fileName = "email/" + sender + "_" + recipient + ".txt";    std:?fstream file(fileName);    if (file.is_open()) {        file << emailContent;        file.close();        std::cout << "Email saved to file: " << fileName << std::endl;    }    else {        std::cerr << "Failed to save email to file." << std::endl;   }}int main() {    // 初始化 Winsock    WSADATA wsaData;    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {        std::cerr << "Failed to initialize Winsock." << std::endl;        return 1;   }    // 创建套接字     SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);    if (serverSocket == INVALID_SOCKET) {        std::cerr << "Failed to create socket." << std::endl;        WSACleanup();        return 1;    }    // 绑定地址和端口     sockaddr_in serverAddress{};    serverAddress.sin_family = AF_INET;    serverAddress.sin_port = htons(25);  // SMTP 默认端口     serverAddress.sin_addr.s_addr = INADDR_ANY;    if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == SOCKET_ERROR) {        std::cerr << "Failed to bind." << std::endl;        closesocket(serverSocket);        WSACleanup();        return 1;   }    // 监听连接请求     if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) {        std::cerr << "Failed to listen." << std::endl;        closesocket(serverSocket);        WSACleanup();        return 1;   }    std::cout << "Server started. Listening for incoming connections…" << std::endl;    while (true) {        // 接受客户端连接         SOCKET clientSocket = accept(serverSocket, nullptr, nullptr);        if (clientSocket == INVALID_SOCKET) {            std::cerr << "Failed to accept client connection." << std::endl;            closesocket(serverSocket);            WSACleanup();            return 1;        }        std::cout << "Client connected." << std::endl;        const std::string welcomeMessage = "220 Welcome to My Mail Server\\r\\n";        send(clientSocket, welcomeMessage.c_str(), welcomeMessage.size(), 0);        // 接收客户端的命令         std::string command;        if (!receiveCommand(clientSocket, command)) {            std::cerr << "Error receiving command." << std::endl;            closesocket(clientSocket);            continue;        }        // 判断命令是否为 EHLO        if (command.substr(0, 4) == "EHLO") {            // 发送 EHLO 响应             std::string response = "250-Hello gru.win\\r\\n"                "250-SIZE 52428800\\r\\n"                "250-8BITMIME\\r\\n"                "250-ENHANCEDSTATUSCODES\\r\\n"                "250-PIPELINING\\r\\n"                "250-CHUNKING\\r\\n"                "250 OK\\r\\n";            send(clientSocket, response.c_str(), static_cast<int>(response.size()), 0);            if (!receiveCommand(clientSocket, command)) {                std::cerr << "Error receiving command." << std::endl;                closesocket(clientSocket);                continue;            }        }        std::string sender;        std::string recipient;        while (command.length() >= 4)        {            switch (MAKE_INT32(command))            {            case MAKE_INT32("MAIL"):                // 收到 MAIL FROM 命令,获取发件人信息                 sender = parseSender(command);                break;                    // 判断下一个命令是否为 RCPT TO            case MAKE_INT32("RCPT"):                // 获取收件人信息                 recipient = parseRecipient(command);                break;                //const std::string welcomeMessage = "250 OK\\r\\n";                //send(clientSocket, welcomeMessage.c_str(), welcomeMessage.size(), 0);                // 接收下一个命令                 // 判断下一个命令是否为 DATA            case MAKE_INT32("DATA"):                // 发送接收数据的响应                 std::string dataResponse = "354 Start mail input; end with <CRLF>.<CRLF>\\r\\n";                send(clientSocket, dataResponse.c_str(), static_cast<int>(dataResponse.size()), 0);                // 接收邮件内容                 std::string emailContent;                while (true) {                    char buffer[BUFFER_SIZE];                    int bytesRead = recv(clientSocket, buffer, BUFFER_SIZE – 1, 0);                    if (bytesRead <= 0) {                        std::cerr << "Error receiving email content." << std::endl;                        break;                    }                    buffer[bytesRead] = \’\\0\’;                    emailContent += buffer;                    // 判断是否接收完毕                     if (emailContent.length() >= 5 && emailContent.substr(emailContent.length() – 5) == "\\r\\n.\\r\\n") {                        break;                    }                }                // 保存邮件到文件                 saveEmailToFile(emailContent, sender, recipient);                break;            case MAKE_INT32("QUIT"):                break;            default:                break;            }            // 发送接收成功的响应             std::string response = "250 OK\\r\\n";            send(clientSocket, response.c_str(), static_cast<int>(response.size()), 0);            if (!receiveCommand(clientSocket, command)) {                std::cerr << "Error receiving command." << std::endl;                closesocket(clientSocket);                break;            }        }        // 关闭客户端连接         closesocket(clientSocket);        std::cout << "Client disconnected." << std::endl;    }    // 关闭服务器套接字     closesocket(serverSocket);    // 清理 Winsock    WSACleanup();    return 0;} 将接收到的邮件保存到 txt 文本文件,用来接收验证码超级给力,纯中文与 chatgpt3.5 交互获得的代码,真没想到中文编程会以这种方式实现 Wise 指南 2023-06-09 16:50 2 这个怎么解析 mime 呢?邮件不都是纯 plain 的呀。不过也够牛屄啦。chenyunzhui 2023-06-09 16:52 3Wise 指南 发表于 2023-6-9 16:50 这个怎么解析 mime 呢?邮件不都是纯 plain 的呀。不知道,反正邮件已源文件保存到 txt 文件了,解析更多内容需要继续对 gpt 进行拷问才行,问了至少 6 个小时才给我这么点东西,不过测试确实能收邮件

正文完
 0