共计 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 个小时才给我这么点东西,不过测试确实能收邮件