如何使用套接字C++发送邮件
How to send mail using socket C++
我正在使用套接字将邮件从我的 Gmail acc 发送到我的 Gmail acc 以避免 SSL 和身份验证,但我不知道 Gmail 是否以某种方式阻止了这些端口 TLS(垃圾邮件原因(,因为我没有收到任何东西,垃圾邮件文件夹是空的。
如果有人对这个话题有经验,我将不胜感激。
int main() {
cout << "send mail" << endl;
char arr[] = "gmail-smtp-in.l.google.com";
char* ptrServer = arr;
char arr0[] = "someaddress@gmail.com";
char* ptrReceiver= arr0;
char arr1[] = "someaddress@gmail.com";
char* ptrSender = arr1;
char arr2[] = "- Some Data -";
char* ptrSubject = arr2;
char arr3[] = "Hello from the PC";
char* ptrMessage = arr3;
sendEmail(ptrServer, ptrReceiver, ptrSender, ptrSubject, ptrMessage);
cin >> arr;
return 0;
}
这是我用于发送邮件的功能(我不知道您需要为 TLS 发送什么,我只是发送这个顺序 EHLO 和 STARTTLS(
void sendEmail(char * server, char * to, char * from, char * subject, char * message) {
SOCKET sockfd;
WSADATA wsaData;
hostent* host;
sockaddr_in dest;
char szSmtpServerName[64] = "";
int sent;
char line[256];
if (WSAStartup(0x202, &wsaData) != SOCKET_ERROR) {
if ((host = gethostbyname(server)) != NULL) {
memset(&dest, 0, sizeof(dest));
memcpy(&(dest.sin_addr), host->h_addr, host->h_length);
dest.sin_family = host->h_addrtype;
dest.sin_port = htons(25);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
connect(sockfd, (struct sockaddr*) & dest, sizeof(dest));
strcpy_s(line, "EHLOn");
sent=send(sockfd, line, strlen(line),0);
Sleep(500);
strcpy_s(line, "STARTTLSn");
sent = send(sockfd, line, strlen(line), 0);
Sleep(500);
strcpy_s(line, "MAIL FROM:<");
strncat_s(line, from, strlen(from));
strncat_s(line, ">n", 3);
sent = send(sockfd, line, strlen(line), 0);
Sleep(500);
strcpy_s(line, "RCPT TO:<");
strncat_s(line, to, strlen(to));
strncat_s(line, ">n", 3);
sent = send(sockfd, line, strlen(line), 0);
Sleep(500);
strcpy_s(line, "DATAn");
sent = (send(sockfd, line, strlen(line), 0));
Sleep(500);
strcpy_s(line, "To: ");
strcat_s(line, to);
strcat_s(line, "n");
strcat_s(line, "From: ");
strcat_s(line, from);
strcat_s(line, "n");
strcat_s(line, "Subject: ");
strcat_s(line, subject);
strcat_s(line, "n");
strcat_s(line, message);
strcat_s(line, "rn.rn");
sent = send(sockfd, line, strlen(line), 0);
Sleep(500);
strcpy_s(line, "quitn");
sent = send(sockfd, line, strlen(line), 0);
Sleep(500);
}
}
closesocket(sockfd);
WSACleanup();
cout << "mail was sent" << endl;
}
SMTP的完整规范是一个公开可用的文档。如果您查看 SMTP 的这些正式规范,您将很容易发现所显示代码的许多基本问题。
1( 建立连接后,发件人必须等待服务器的初始问候消息。显示的代码会立即发送EHLO
命令,而无需等待。
2(发送EHLO
命令后,发送方必须等待服务器的响应,而不是等待500毫秒,并处理响应。
3( EHLO 命令可能会失败,因为它是一个扩展;如果是这样,发件人必须回退到 HELO。不太可能,使用现代SMTP服务器,但必须准备好处理强大的程序。
4( 在所有情况下,服务器的响应都可能指示错误和/或拒绝接受邮件。显示的代码无法执行任何错误检查。
5(发送STARTTLS
命令后,发送方必须等待服务器的响应,如果命令成功,发送方必须发起TLS协商。显示的代码无法执行此操作。
6( 进行 TLS 协商并建立加密连接后,SMTP 会话将从初始状态重新启动,从 EHLO/HELO 状态重新启动,而不是MAIL FROM
。
您不能采取任何简单的捷径,例如在规定的时间内休眠,而不是正确处理服务器回复。随着时间的推移,这将无法可靠地工作。它似乎有效,一两次,但最终会破裂。这是一个保证。您必须正确且全面地实现 SMTP 的每个部分,并正确实现它。
由于您使用的是Microsoft Windows,因此您应该在Microsoft的文档中找到有关在MS-Windows上使用TLS的完整文档。显然,这是一个非常大的主题,根本不会被逐字复制到这个答案或 Stackoverflow 上的任何其他答案中。有关详细信息,请参阅 MSDN 或其他位置的 Microsoft 文档。
这些都是相当复杂的大型技术编程主题。你不会在Stackoverflow或任何其他公共论坛上找到完整的描述,简化为一个完整的,一个或两个段落的答案。任何人都能告诉您的唯一事情是参考技术文档以获取特定协议如何工作的完整规范。知道在哪里可以找到以及如何阅读技术文档是每个C++开发人员都需要知道如何做的事情。
您还很可能会发现MS-Windows可能会提供一个SMTP客户端库,该库可以正确,正确地处理SMTP的所有方面,包括TLS,而无需担心您的代码。这样的SMTP客户端库是否可用,只有在查阅Microsoft的技术文档后才能确定。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- C++:TypeDef使用元组
- 使用std::multimap迭代器创建std::list
- 从不同线程使用int64的不同字节安全吗
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么在全局范围内使用"extern int a"似乎不行?
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用Google Mock来模拟gettimeofday()
- 如何使用默认参数等选择模板专业化
- 为什么使用 "this" 指针调用派生成员函数?
- 使用新行和不使用新行读取文件
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 如何确定我已使用非编码文件到达 EOF?
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 使用CMake创建QML插件
- 使用 LLVM 的 libc++ 时,__1 符号从何而来?
- 在std::cout之后使用std::cin时,换行符从何而来
- 为什么以及在何处在C++中使用引用和指针
- 基例如何影响使用递归函数的哪些行