C语言实现发送邮件功能

 更新时间:2022年06月15日 10:28:18   作者:Paul0415  
这篇文章主要为大家详细介绍了C语言实现发送邮件功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C语言实现发送邮件的具体代码,供大家参考,具体内容如下

首先需要知道发送邮件的服务器IP地址和端口,我这里使用的是网易的126邮箱,如果是其他邮箱需要替换成其他的邮箱域名,域名和端口一般可以在邮箱网页的帮助项里面找到。用域名比较方便维护以免后续更换ip之后还要修改代码。

发送邮件一共需要8个步骤,具体见代码main函数里面的注释

代码中的用户名密码以及收件人发件人等信息需要修改为你自己的。而且用户名和密码需要进行base64编码后才能发送,具体base64算法没有贴了,百度上到处都是。

完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include "winsock2.h"

extern int Base64Encod(char * data,char *output,int len,int *oputlen);

#define EMAIL_SERVER     "smtp.126.com"  //按需修改

int CreateSocketAndConnect()
{
    struct sockaddr_in server_addr;
    struct hostent *Addr;
    int ret;

    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock < 0){
        printf("sock create failed\n");
        return -1;
    }

    Addr = gethostbyname(EMAIL_SERVER);    //用域名获取对应IP
    if(Addr == NULL){
        printf("get ip error\n");
        return -1;
    }
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(25);
    server_addr.sin_addr.S_un.S_addr = (*(struct in_addr*)Addr->h_addr_list[0]).S_un.S_addr;
    ret = connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if(ret < 0){
        printf("connect server failed\n");
        return -1;
    }

    return sock;
}

int server_send_recv_display(int sock, char *buff)
{
    int ret = 0;
    char recvbuff[320] = {0};

    send(sock, buff, strlen(buff), 0);
    ret = recv(sock, recvbuff, 320, 0);
    printf("服务器返回消息:len = %d \n recv:[%s] \n",ret,recvbuff);

    return ret;
}

/*HELO*/
int email_send_helo_fun(int sock)
{
    char buff[320] = {0};
    int ret;

    sprintf(buff, "HELO 126.com\r\n");
    ret = server_send_recv_display(sock, buff);
    if(ret <= 0)
    {
        return -1;
    }

    return 0;
}

/*AUTH LOGIN 身份认证*/
int email_send_authlogin_fun(int sock)
{
    char buff[320] = {0};
    int ret;

    sprintf(buff,"%s","AUTH LOGIN\r\n");
    ret = server_send_recv_display(sock, buff);
    if(ret <= 0)
    {
        return -1;
    }

    return 0;
}

//发送用户名
int email_send_username_fun(int sock)
{
    char buff[320] = {0};
    char encbuff[120] = {0};
    int ret, len = 0;

    sprintf(buff, "xxxxxxxxxx@126.com");    //需要改成自己的用户名
    Base64Encod(buff, encbuff, strlen(buff), &len);
    memset(buff, 0x00, sizeof(buff));
    sprintf(buff,"%s\r\n",encbuff);
    ret = server_send_recv_display(sock, buff);
    if(ret <= 0)
    {
        return -1;
    }

    return 0;
}


//发送密码
int email_send_password_fun(int sock)
{
    char buff[320] = {0};
    char encbuff[120] = {0};
    int ret, len = 0;

    sprintf(buff, "123456789");          //需要改成自己的密码,有的邮箱是需要填授权码不是登录用的密码
    Base64Encod(buff, encbuff, strlen(buff), &len);
    memset(buff, 0x00, sizeof(buff));
    sprintf(buff, "%s\r\n", encbuff);
    ret = server_send_recv_display(sock, buff);
    if(ret < 0){
        return -1;
    }

    return 0;
}

//发送发件人
int email_send_from_fun(int sock)
{
    char buff[320] = {0};
    int ret;

    sprintf(buff, "MAIL FROM: <xxxxxxxxxx@126.com>\r\n");
    ret = server_send_recv_display(sock, buff);
    if(ret < 0){
        return -1;
    }

    return 0;
}

//发送收件人
int email_send_to_fun(int sock)
{
    char buff[320] = {0};
    int ret;

    sprintf(buff, "RCPT TO: <xxxxxx@163.com>\r\n");
    ret = server_send_recv_display(sock, buff);
    if(ret < 0){
        return -1;
    }

    return 0;
}

//通知服务器准备发送邮件
int email_send_ready_fun(int sock)
{
    char buff[320] = {0};
    int ret;

    sprintf(buff, "DATA\r\n");
    ret = server_send_recv_display(sock, buff);
    if(ret < 0){
        return -1;
    }

    return 0;
}

//发送邮件
int email_send_maintext_fun(int sock)
{
    char buff[320] = {0};
    int ret;

    sprintf(buff, "From: \"pc\"<xxxxxxxxxx@126.com>\r\n"        //发件人
                  "To: \"con\"<xxxxxx@163.com>\r\n"             //收件人
                  "Subject: email test\r\n\r\n"                 //主题
                  "test:\r\n"                                   //正文, 以 \r\n.\r\n 结束
                  "    line1\r\n"
                  "    line2\r\n.\r\n");
    ret = server_send_recv_display(sock, buff);
    if(ret < 0){
        return -1;
    }

    return 0;
}

#define MAX_BUFF_SIZE    512

int main()
{
    int sock;
    char buff[MAX_BUFF_SIZE];
    WSADATA wsa;
    int ret;

    if(WSAStartup(MAKEWORD(1,1), &wsa) != 0){
        printf("WSA startup failed\n");
        return 1;
    }

    sock = CreateSocketAndConnect();
    if(sock < 0){
        return -1;
    }

    printf("connect to server success\n");

    memset(buff, 0x00, sizeof(buff));
    while(1){
        ret = recv(sock, buff, MAX_BUFF_SIZE, 0);
        if(ret < 0){
            printf("recv error\n");
            continue;
        }

        printf("%s", buff);
        break;
    }

    //1.send helo
    if(email_send_helo_fun(sock) < 0){
        return 1;
    }

    //2.send auth login
    if(email_send_authlogin_fun(sock) < 0){
        return 1;
    }

    //3.send username
    if(email_send_username_fun(sock) < 0){
        return 1;
    }

    //4.send password
    if(email_send_password_fun(sock) < 0){
        return 1;
    }

    //5.send from
    if(email_send_from_fun(sock) < 0){
        return 1;
    }

    //6.send to
    if(email_send_to_fun(sock) < 0){
        return 1;
    }

    //7.send notice ready
    if(email_send_ready_fun(sock) < 0){
        return 1;
    }

    //8.send email
    if(email_send_maintext_fun(sock) < 0){
        return 1;
    }

    closesocket(sock);

    return 0;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

您可能感兴趣的文章:

相关文章

  • c++内联函数(inline)使用详解

    c++内联函数(inline)使用详解

    这篇文章主要介绍了c++内联函数(inline)使用详解,需要的朋友可以参考下
    2014-04-04
  • 详解C++ 引用

    详解C++ 引用

    这篇文章主要介绍了C++ 引用的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • C++中点操作符和箭头操作符的使用详解

    C++中点操作符和箭头操作符的使用详解

    本篇文章介绍了,C++中点操作符和箭头操作符的使用详解。需要的朋友参考下
    2013-05-05
  • Qt实现编辑数据库数据的方法详解

    Qt实现编辑数据库数据的方法详解

    这篇文章主要为大家详细介绍了Qt是如何实现编辑数据库数据的,文中的示例代码简洁易懂,对我们深入了解QT有一定的帮助,感兴趣的小伙伴可以了解一下
    2023-02-02
  • C语言实现linux网卡检测精简版

    C语言实现linux网卡检测精简版

    这篇文章主要为大家详细介绍了C语言实现linux网卡检测的精简版,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • c++的glog与spdlog的性能对比测试分析

    c++的glog与spdlog的性能对比测试分析

    这篇文章主要为大家介绍了c++的glog与spdlog的性能对比测试分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • C语言Static 关键字解析

    C语言Static 关键字解析

    这篇文章主要介绍了C语言Static 关键字解析,C语言中staic关键字很简单,简单到你的任何一个项目中可以不写一个staic关键字也是没有问题的。写这篇章主要是一下自己的staic的理解和应用,当然在章开头依旧要照本宣科简述一下static关键字,需要的朋友可以参考一下
    2022-02-02
  • C++利用模板实现消息订阅和分发功能

    C++利用模板实现消息订阅和分发功能

    C++语言支持重载,模板,虚函数等特性,为编写高性能可扩展的程序提供了利器。本文就讲利用模板实现消息订阅和分发功能,感兴趣的小伙伴可以了解一下
    2022-12-12
  • 使用CMake构建一个简单的C++项目的实现

    使用CMake构建一个简单的C++项目的实现

    CMake是一个跨平台的自动化构建工具,可以用于构建各种类型的项目,本文主要介绍了使用CMake构建一个简单的C++项目,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • C语言金币阵列问题解决方法

    C语言金币阵列问题解决方法

    这篇文章主要介绍了C语言金币阵列问题解决方法,主要涉及数组的灵活运算,是一类非常经典的算法,需要的朋友可以参考下
    2014-09-09

最新评论