zoukankan      html  css  js  c++  java
  • C++实现 电子邮件客户端程序(简易版)

    #Windows操作系统下

    • 用命令行工具实现发送邮件(编程前工作)

      步骤:

      1.telnet连接服务器(以用QQ邮箱向网易邮箱发送邮件为例,端口号25)

      

      2.返回220 说明连接成功

       

      3.ehlo发送用户名(QQ邮箱用户名默认是QQ号)

        返回了一堆登录方式码

      

      4.常用auth login登录方式

        返回334,成功

      

      5.输入base64编码后的QQ邮箱账号和密码(为了保护数据)

      在线转码:http://www1.tc711.com/tool/BASE64.htm

      (马赛克部分分别是账号,密码)

      返回 334,235表示成功

      

      6.输入发件地址和收件地址

      返回250 OK为成功

      

      7.data命令表示要开始输入发送的数据了

      按照邮件格式:

        from:<发件地址>

        to:<收件地址>

        subject:主题

        ......内容......

        .   //输入一个点,表示内容结束了,回车即发送该邮件

      

      8.查看163邮箱是否接收到邮件

    • 代码实现
    #include <iostream>
    #include <string>
    #include <WinSock2.h> //适用平台 Windows
    using namespace std;
    #pragma comment(lib, "ws2_32.lib") /*链接ws2_32.lib动态链接库*/
    
    int main()
    {
         char buff[500]; //recv函数返回的结果
         string message;
         string info;
         string subject;

         WSADATA wsaData;
         WORD wVersionRequested = MAKEWORD(2, 1);
         //WSAStarup,即WSA(Windows SocKNDs Asynchronous,Windows套接字异步)的启动命令
         int err = WSAStartup(wVersionRequested, &wsaData);
        // cout << "WSAStartup:" << err << endl;
         SOCKET sockClient; //客户端的套接字
         sockClient = socket(AF_INET, SOCK_STREAM, 0); //建立socket对象

         HOSTENT* pHostent;//hostent是host entry的缩写,该结构记录主机的信息,包括主机名、别名、地址类型、地址长度和地址列表

         pHostent = gethostbyname("smtp.qq.com"); //得到有关于域名的信息,链接到qq邮箱服务器

         SOCKADDR_IN addrServer; //服务端地址
         addrServer.sin_addr.S_un.S_addr = *((DWORD *)pHostent->h_addr_list[0]); //得到smtp服务器的网络字节序的ip地址
         addrServer.sin_family = AF_INET;
         addrServer.sin_port = htons(25); //连接端口25
         //int connect (SOCKET s , const struct sockaddr FAR *name , int namelen ); //函数原型
         err = connect(sockClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)); //向服务器发送请求
         //cout << "connect:" << err << endl;
         buff[recv(sockClient, buff, 500, 0)] = '';
        // cout << "connect:" << buff << endl;
         /*
         登录邮件服务器
         */
         message = "ehlo qq.com ";
         send(sockClient, message.c_str(), message.length(), 0); //发送ehlo命令
         buff[recv(sockClient, buff, 500, 0)] = '';   //接收返回值
        // cout << "helo:" << buff << endl;     //输出返回值

         message = "auth login ";
         send(sockClient, message.c_str(), message.length(), 0);
         buff[recv(sockClient, buff, 500, 0)] = '';
         //cout << "auth login:" << buff << endl;
         /*
         发送base64加密的用户名、密码
         */

         message = "XXXXXXXX "; //base64 编码的用户名
         send(sockClient, message.c_str(), message.length(), 0);
         buff[recv(sockClient, buff, 500, 0)] = '';
         //cout << "usrname:" << buff << endl;

         message = "XXXXXXXXXXXX ";//base64 编码的密码
         send(sockClient, message.c_str(), message.length(), 0);
         buff[recv(sockClient, buff, 500, 0)] = '';
        // cout << "password:" << buff << endl;
         /*
         使用 MAIL 命令指定发送者
         使用 RCPT 命令指定接收者,可以重复使用RCPT指定多个接收者
         */

         string mail;
         cout << "输入收件人邮箱:";
         cin >> mail;
         message = "MAIL FROM:<XXX@qq.com> RCPT TO:<";
        // message = "MAIL FROM:<XXX@qq.com> RCPT TO:<XXX@163.com> ";

         message.append(mail);
         message.append("> ");
         //cout << "message=" << message;

         send(sockClient, message.c_str(), message.length(), 0);

         buff[recv(sockClient, buff, 500, 0)] = '';
        // cout << "mail from: " << buff << endl;
         buff[recv(sockClient, buff, 500, 0)] = '';
        // cout << "rcpt to: " << buff << endl;
         /*
         使用 DATA 命令告诉服务器要发送邮件内容
         */
         message = "DATA ";
         send(sockClient, message.c_str(), message.length(), 0);
         buff[recv(sockClient, buff, 500, 0)] = '';
         //cout << "data: " << buff << endl;

        message = "From: XXX@qq.com
        To: XXX@163.com
        subject:";

        cout<<"主题:";
        cin>>subject;
        message.append(subject);
        message.append(" ");
        cout<<"内容:";
        cin>>info;
        message.append(info);
        message.append(" . ");

       // cout<<"message="<<message;

         /*message = "From: XXX@qq.com
        To: XXX@163.com
        subject: test
        Just a test!
        your friend
        Ctt . "; //注意subject关键字与正文之间要有一个空行*/

         send(sockClient, message.c_str(), message.length(), 0);
         message = "QUIT ";
         send(sockClient, message.c_str(), message.length(), 0);
        buff[recv(sockClient, buff, 500, 0)] = '';
         //cout << "QUIT:" << buff << endl;

         cout << "发送成功!"<<endl;
         system("pause");
    }

      运行界面

      

      查看邮箱(有bug,主题没有正确设定)

      

    • 常见报错的解决方式与注意事项:

      1.保持网络畅通

      2.报错502 有时候指令不能被识别,就重新输入一次指令,再试

      

  • 相关阅读:
    Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging
    KDiff3使用指南
    Win10解决修改host没有权限问题(其他文件同理) 一步都不能少哦:先添加再授权
    微信小程序
    MyBatisSystemException 【exception】
    [LeetCode] Additive Number 加法数
    [CareerCup] 14.5 Object Reflection 对象反射
    C Memory Layout C语言中的内存布局
    strtol 函数用法
    [CareerCup] 14.4 Templates Java模板
  • 原文地址:https://www.cnblogs.com/cttcarrotsgarden/p/10154139.html
Copyright © 2011-2022 走看看