1. 主页 > 好文章

C语言发送带附件邮件的实现方法与常见问题解析


你写了个牛逼的监控程序,设备运行数据都存成日志文件了,但每次还得手动发邮件给老板?就像新手如何快速涨粉需要工具辅助,今天教你的这招能让程序自动发邮件带附件,看完直接甩掉人工操作!


〇、先搞清楚游戏规则

发带附件的邮件和普通邮件有啥区别?咱们打个比方:普通邮件就像寄信,带附件相当于往信封里塞照片。但计算机世界讲究格式,得按MIME协议打包——这玩意儿就像快递公司的包装规范,不按规矩来分分钟被拒收。

??必须知道的三个术语??:

  1. multipart混合内容(相当于快递包裹里的分隔板)
  2. Content-Disposition(标记这是附件)
  3. base64编码(把二进制文件转成字母安全运输)

一、上代码前先备料

  1. ??开发环境确认??

    • 已经装好libcurl库(没装的翻我上篇教程)
    • 准备测试用的PDF或txt文件(别用大文件!)
  2. ??邮箱账号要点??

    邮箱类型支持附件大小特别要求
    16350MB需要客户端授权码
    QQ邮箱35MB开启SMTP服务
    Gmail25MB启用"不安全应用"

二、手把手写附件发送代码

咱们分两步走:先写个能发文字邮件的,再升级成带附件的。看好了啊!

??基础版代码框架??:

c复制
#include 

// 回调函数提供邮件内容
size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp) {
    const char *data[] = {
        "From: 监控系统 \r\n",
        "To: 技术部 \r\n",
        "Subject: 每日运行报告\r\n",
        "\r\n",  // 头部和正文的分隔空行
        "今日设备运行正常,详见附件。\r\n",
        NULL
    };
    
    static size_t index = 0;
    if(!data[index]) return 0;
    
    size_t len = strlen(data[index]);
    memcpy(ptr, data[index], len);
    index++;
    
    return len;
}

??重点改造部分??:

c复制
// 在payload_source里改成这样:
const char *data[] = {
    "From: 监控系统 \r\n",
    "To: 技术部 \r\n",
    "Subject: 带附件的测试邮件\r\n",
    "MIME-Version: 1.0\r\n",
    "Content-Type: multipart/mixed; boundary=\"BOUNDARY123\"\r\n",
    "\r\n--BOUNDARY123\r\n",  // 正文部分开始
    "Content-Type: text/plain; charset=utf-8\r\n",
    "\r\n今日设备运行正常,详见附件。\r\n",
    "\r\n--BOUNDARY123\r\n",  // 附件部分开始
    "Content-Disposition: attachment; filename=\"log.txt\"\r\n",
    "Content-Transfer-Encoding: base64\r\n",
    "\r\n",  // 这里插入base64编码后的文件内容
    "SGVsbG8gV29ybGQhCg==\r\n",  // 示例base64数据(实际需要读取文件)
    "\r\n--BOUNDARY123--\r\n",  // 结束标记
    NULL
};

这时候你肯定要骂娘:这堆乱码似的头信息是人写的?别急,后面教你怎么自动生成。


三、自动处理附件的黑科技

手动写MIME头太反人类,咱们用libcurl的mime接口来搞定:

c复制
// 创建mime结构
curl_mime *mime = curl_mime_init(curl);

// 添加文本内容
curl_mimepart *part1 = curl_mime_addpart(mime);
curl_mime_data(part1, "今日设备运行正常,详见附件。", CURL_ZERO_TERMINATED);
curl_mime_type(part1, "text/plain");

// 添加附件
curl_mimepart *part2 = curl_mime_addpart(mime);
curl_mime_filedata(part2, "/var/log/device.log");  // 你的日志文件路径
curl_mime_filename(part2, "daily_report.log");  // 邮件中显示的文件名

// 配置到curl对象
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);

这就舒服多了吧?不过要注意文件路径权限问题,特别是Linux系统下别忘记给程序访问权限。


四、99%新手都会踩的坑

下面这个对照表建议收藏,都是我亲自踩出来的经验:

现象可能原因解决办法
附件变成乱码忘记base64编码使用curl_mime_encoder设置
收到空附件文件路径错误用绝对路径代替相对路径
附件大小被截断超出邮件服务器限制压缩文件或分多个邮件发送
Windows下发送失败文件被其他程序占用关闭Excel等可能占用的软件
收到警告邮件被判定为垃圾邮件添加DKIM签名(企业邮箱专属)

小编碎碎念

说实话,用C语言发带附件邮件就像用算盘打游戏——能玩,但肯定不如游戏机爽。如果是新项目,建议优先考虑Python这种现代语言。但话说回来,很多老系统改造项目根本没得选,这时候今天教的方法就是救命稻草了。

最后提醒各位:千万别在代码里明文存密码!见过太多实习生把企业邮箱密码上传到GitHub,第二天就被黑客群发钓鱼邮件。安全这事儿,怎么小心都不为过。

本文由嘻道妙招独家原创,未经允许,严禁转载