In the project, we needed to use the SMTP protocol to send email alerts, with the backend technology stack primarily being Java and C++. For the Java project, we found a ready-made class online that worked perfectly. We tested it successfully with 163 Mail, Tencent Mail, and Ali Mail. Unfortunately, our C++ project also required the use of the SMTP protocol to send emails. We initially searched online, investigating CSDN for examples. While there were plenty of examples, each had comments indicating various problems. Upon copying and running the code, the 163 Mail tested perfectly. However, when we tested with DingTalk Mail, we encountered authentication issues. It was clear we needed to thoroughly understand the SMTP protocol before proceeding.

Send the EHLO command to declare identity and indicate that authentication is required. Note that this part needs to be verified via Telnet, either as [email protected] or user, or errors may occur.
Send the AUTH LOGIN command to log into the mailbox, which usually requires Base64 encoding.
Send the MAIL command to initiate the email transfer, followed by the senderâs email address (return address). Itâs also used to notify the sender if the email couldnât be delivered. To ensure successful delivery, the senderâs address should be accepted by the recipient or intermediaries. This command clears related buffers to prepare for new mail.
Send the RCPT command, which informs the recipient of the recipientâs email address. If there are multiple recipients, this RCPT TO command must be used multiple times, specifying one recipient each time. If the recipientâs server refuses to forward the email, it must respond with error code 550. If the server agrees, it modifies the email delivery path from the original destination (this server) to the next.
Send the DATA command. The recipient treats the data following this command as the message data. The data is added to the buffer and terminated with a line containing only a period (â.â). For the recipient, this indicates the start of data transfer from the buffer, and after the transfer ends, the buffer gets cleared. If the transfer is accepted, the recipient replies with OK.
Send the QUIT command. SMTP requires the recipient to respond with OK and then terminate the transmission. The recipient should not interrupt the connection until it receives and responds to this command with OK, preventing disconnections even if transmission errors occur. The sender also must not break the connection before issuing this command and receiving an OK response.
After grasping the basic procedure and capturing the data packets, C++ simply needs to send data in this format to achieve authentication. Suspecting issues with username and password transmission, we captured the data packets sent by C++ and found that the Base64 value for User differed while Pass was identical. Decoding Base64 revealed one as [email protected] and the other as user, which pointed to the problem. 163 Mail required the format as user, while DingTalk Mail required [email protected]. After correction, authentication succeeded, and emails sent successfully. However, the story didnât end there⊠A week later, after handing the project to testers, they reported that alert emails werenât being sent. Impossible, I thought. Running the project proved otherwiseâemails could only be sent once, then no more. Had DingTalk blocked us? Java tests showed no issues, so we resumed packet capturing. Authentication was fine, yet the emails werenât received.


The differences were obviousâthe formats for From and To were incorrect, and the Content-Type was wrong. Crucially, there was no Message-ID field. Focusing on this, I analyzed the Message-ID. Capturing multiple comparisons showed each Message-ID differed, leading me to suspect it caused C++âs failure to send more than once. I added the following code in C++:
The run was successful, but another attempt failed. Changing the Message-ID value to 2 worked again, confirming the issue lay there. Finally solved, we set the Message-ID as: machine name + random number.