Computer network course design mail client

1. Subject
Email client

2. Environment
Win10 codeblocks

Three, code implementation

SMTP and POP3 process diagram

1

There are a few steps to prepare to use the computer’s mail service.

One is that the computer needs to open the tallnet service. Please refer to Baidu or Google for more details.
The second is to send emails using the stmp protocol. I send emails using qq mailbox, so I need to go to the account in the qq mailbox settings, open the stmp service, and write down the generated authorization code. The authorization code is the password for the third-party login. Both the user name and authorization code must be base64 encoded, and the URL is below.
The third is to use the pop3 protocol to receive mail, and I receive mail using 163 mailboxes. The mailbox number and authorization code here do not need to be base64 encoded.

base64 encrypted URL

I have marked the places where your username and authorization code are needed in the code.

In addition, you also need to know the format and commands for sending and receiving mail.
This can be practiced by using the Windows command line to practice the use of these commands, specifically please Baidu or Google.


#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#include <unistd.h>
#include <string>
using namespace std;
#pragma comment(lib, "ws2_32.lib") /*链接ws2_32.lib动态链接库*/

int main() {
    
    
    char buff[50000]; //收到recv函数返回的结果
    string message;
    string info;
    string subject;
    WSADATA wsaData;
    WORD wVersionRequested = MAKEWORD(2, 1);
    int err = WSAStartup(wVersionRequested, &wsaData);
    SOCKADDR_IN addrServer;
    HOSTENT *pHostent;
    SOCKET sockClient;
    cout << "你想查看邮件还是发邮件?\n\t1.查看邮箱\n\t2.发送邮件\n";
    int call;
    cin >> call;
    if (call == 2) {
    
    
        sockClient = socket(AF_INET, SOCK_STREAM, 0);
        pHostent = gethostbyname("smtp.qq.com");
        addrServer.sin_addr.S_un.S_addr = *((DWORD *) pHostent->h_addr_list[0]);
        addrServer.sin_family = AF_INET;
        addrServer.sin_port = htons(25);
        err = connect(sockClient, (SOCKADDR *) &addrServer, sizeof(SOCKADDR));
        buff[recv(sockClient, buff, 500, 0)] = '\0';
        message = "ehlo qq.com\r\n";
        send(sockClient, message.c_str(), message.length(), 0); //发送ehlo命令
        buff[recv(sockClient, buff, 500, 0)] = '\0';   //接收返回值
        message = "auth login\r\n";
        send(sockClient, message.c_str(), message.length(), 0);

        message = "此处填写你的qq邮箱用户名(无后缀)的base64加密后的码\r\n";//qq邮箱用户名的base64加密后内容
        send(sockClient, message.c_str(), message.length(), 0);
        buff[recv(sockClient, buff, 500, 0)] = '\0';
        message = "此处填写你的qq邮箱授权码的base64加密后的码\r\n";//qq邮箱授权码的base64加密后内容
        send(sockClient, message.c_str(), message.length(), 0);
        buff[recv(sockClient, buff, 500, 0)] = '\0';
        string mail;
        cout << "请输入收件人邮箱:";
        cin >> mail;

        message = "MAIL FROM:<此处填写你发邮件的邮箱号(有后缀)> \r\nRCPT TO:<";
        message.append(mail);
        message.append("> \r\n");
        send(sockClient, message.c_str(), message.length(), 0);
        buff[recv(sockClient, buff, 500, 0)] = '\0';

        message = "DATA\r\n";
        send(sockClient, message.c_str(), message.length(), 0);
        buff[recv(sockClient, buff, 500, 0)] = '\0';
        message = "From: 此处填写你发邮件的邮箱号(有后缀)\r\nTo: " + mail + "\r\nsubject:";
        cout << "主题:";
        cin >> subject;
        message.append(subject);
        message.append("\r\n\r\n");
        cout << "内容:";
        cin >> info;
        message.append(info);
        message.append("\r\n.\r\n");
        send(sockClient, message.c_str(), message.length(), 0);
        message = "QUIT\r\n";
        send(sockClient, message.c_str(), message.length(), 0);
        buff[recv(sockClient, buff, 500, 0)] = '\0';

        cout << "发送成功!" << endl;
        //system("pause");
    }
    if (call == 1) {
    
    
        sockClient = socket(AF_INET, SOCK_STREAM, 0);
        const char *host_id = "pop3.126.com";
        pHostent = gethostbyname("pop.163.com");
        int port = 110;
        addrServer.sin_addr.S_un.S_addr = *((DWORD *) pHostent->h_addr_list[0]);
        addrServer.sin_family = AF_INET;
        addrServer.sin_port = htons(port);
        err = connect(sockClient, (SOCKADDR *) &addrServer, sizeof(SOCKADDR));
        buff[recv(sockClient, buff, 500, 0)] = '\0';

        message = "user 你的163邮箱号(有后缀,不用base64编码)\r\n";
        send(sockClient, message.c_str(), message.length(), 0);
        buff[recv(sockClient, buff, 500, 0)] = '\0';
        cout << "Client : send name \nServer:"
                  << buff << endl;

        message = "pass 163邮箱的授权码(不用base64编码)\r\n";
        send(sockClient, message.c_str(), message.length(), 0);
        buff[recv(sockClient, buff, 500, 0)] = '\0';
        cout << "Client : send pass \nServer:"
                  << buff << endl;

        message = "stat\r\n";
        send(sockClient, message.c_str(), message.length(), 0);
        buff[recv(sockClient, buff, 500, 0)] = '\0';
        Sleep(1);
        cout << "Client : send stat \nServer : "
                  << buff << endl;

        message = "list\r\n";
        send(sockClient, message.c_str(), message.length(), 0);
        buff[recv(sockClient, buff, 50000, 0)] = '\0';
        Sleep(1);
        cout << "Client : send list \nServer :"
                  << buff << endl;
        int n;
        cout << "你先想查看那一封邮件?输入序号"
                  << endl;
        cin >> n;
        message = "retr " + to_string(n) + "\r\n";

        send(sockClient, message.c_str(), message.length(), 0);
        Sleep(1);
        cout << "Client : send retr "<<n<<"\n";
        buff[recv(sockClient, buff, 50000, 0)] = '\0';
        cout << "Server :" << buff << endl;

        message = "QUIT\r\n";
        send(sockClient,message.c_str(),strlen(buff),0);
        Sleep(1);
        buff[recv(sockClient, buff, 50000, 0)] = '\0';
        cout << "Quit Receive: " << buff << endl;

        closesocket(sockClient);
        WSACleanup();

    }
}


4. Experimental results

send email:
Insert picture description here


Email view:

Insert picture description here

Insert picture description here


V. Summary and gains At
first I used qq mailbox to send emails, but no matter how I changed it, I couldn't send them successfully, even if the window showed that the sending was successful. Later, I changed to 163 mailbox to send emails. Well, it succeeded without fail. Later, I used qq mailbox to send emails, um, it still failed. I wonder if the computer’s service is not open, or the qq mailbox is stricter than 163 for third-party mail (this is my guess, no verification). Later, it was the first one. After Baidu, I opened a server service that may be related to sending emails, and then I tried to send it. . .
When using the Windows command line to contact and send emails (using qq mailbox to send), the server always disconnects inexplicably, or the login server connection is immediately disconnected after the user name and password are correct. Well, I don't know what happened. But when using 163 mailbox to send, this situation did not occur. Combining this phenomenon with my previous use of QQ and 163, I feel that 163 is more comfortable to use, and there are fewer problems.

If you have any questions, please leave a message to exchange!

Guess you like

Origin blog.csdn.net/weixin_43752257/article/details/112958210