
curl 邮件三协议实战SMTP 发信、POP3 搬箱、IMAP 管箱一次讲清【免费下载链接】Awesome-Chinese-LLM整理开源的中文大语言模型以规模较小、可私有化部署、训练成本较低的模型为主包括底座模型垂直领域微调及应用数据集与教程等。项目地址: https://gitcode.com/GitHub_Trending/aw/Awesome-Chinese-LLMcurl 除了传文件还内置了 SMTP、POP3、IMAP 三套邮件协议发信、收信、管邮箱都能直接对邮件服务器下命令。CI 流水线发告警、老邮箱存量归档、多设备查未读命令行或 libcurl 任选不用自己拼协议字节。 三个协议怎么选发、搬、管对号入座先解决“该用哪一个”三种活对应三个协议30 秒对号入座你要干的活协议通道角色典型场景只把信送出去SMTP投递把信推到对方服务器CI 告警、报表通知把邮件整个搬回本地POP3拉取信件搬回家存量归档、备份、轻量客户端查、搜、改标记IMAP管理远程操作邮箱状态同步多设备共用、按未读筛选、关键词搜索一句话结论发信是 SMTP 的活整箱搬走是 POP3 的活查、搜、改标记这类细活归 IMAP。 连接与认证端口、加密方式与密码的坑这一节把三个协议共用的“起步”问题一次讲清——怎么连、怎么加密、密码用哪种后面所有命令才不会卡第一步。端口与加密方式对照协议明文端口隐式 TLS 端口URL 前缀SMTP25 / 587465smtp://或smtps://POP3110995pop3://或pop3s://IMAP143993imap://或imaps://两种加密的区别在于加密从哪一刻开始。带s的前缀smtps / pop3s / imaps从建连第一个字节就加密明文端口则是先明文接入再按下面四步升级TCP 建连此时还没有任何凭证上路curl 发出 STARTTLS服务器答复“可升级”通道切换为加密随后走 SASL 认证PLAIN / LOGIN 居多235应答代表通过开始业务命令MAIL FROM / RETR / SEARCH最后 QUIT / LOGOUT 收尾。命令行上三种写法要分清--ssl是“能升就升”--ssl-reqd是“升不了就报错”s前缀则从头到尾加密。账号密码走明文等于裸奔生产环境直接上隐式 TLS或至少压到--ssl-reqd。认证默认走 SASL命令行--user 名:密码C 里用CURLOPT_USERNAME/CURLOPT_PASSWORD。最常见的坑是“应用专用密码”不少服务商对第三方客户端登录禁用了常规邮箱密码直接连会吃535先去服务商设置页领一个专用密码再重试。验证方法加-v跑一遍看到认证通过如235之后业务命令才开始说明握手这关已过。 场景一一封告警邮件的完整投递流程curl 发送 SMTP 邮件这一节解决“脚本里给多个收件人发一封告警邮件”命令行和 libcurl 两条路都走通。最小可跑命令curl -v smtp://mail.example.com:587 \ --ssl-reqd --user username:password \ --mail-from senderexample.com \ --mail-rcpt aexample.com \ --mail-rcpt bexample.com \ --upload-file mail.txt--mail-rcpt可以重复写每写一行多一个收件人--upload-file指向正文文件。这里有个大坑文件内容必须是完整的 RFC 5322 文本——头部、空一行、再正文——curl 不会替你补 Subject。只写正文的话收件人看到的是一封没有主题、没有发件人的信。规范的 mail.txt 长这样To: aexample.com From: ci-bot senderexample.com Subject: CI alert Build #1024 failed.验证方法-v会逐行打出 EHLO、MAIL FROM、RCPT TO、DATA每行开头都是三位应答码最后一行落到250 2.0.0 Ok即全员接收成功。libcurl 这边收件人交给字符串列表curl_slist维护正文由读回调分段吐出关键选项是CURLOPT_MAIL_RCPT加CURLOPT_READFUNCTION/CURLOPT_READDATAstatic size_t off 0; static const char *payload To: aexample.com\r\n From: ci-bot senderexample.com\r\n Subject: CI alert\r\n\r\nBuild #1024 failed.\r\n; static size_t read_cb(char *buf, size_t s, size_t n, void *u) { size_t *p u, room s * n, len strlen(payload *p); if (len room) len room; memcpy(buf, payload *p, len); *p len; return len; } int main(void) { CURL *c curl_easy_init(); struct curl_slist *r curl_slist_append(NULL, aexample.com); r curl_slist_append(r, bexample.com); curl_easy_setopt(c, CURLOPT_URL, smtp://mail.example.com:587); curl_easy_setopt(c, CURLOPT_USERNAME, username); curl_easy_setopt(c, CURLOPT_PASSWORD, password); curl_easy_setopt(c, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); curl_easy_setopt(c, CURLOPT_MAIL_FROM, senderexample.com); curl_easy_setopt(c, CURLOPT_MAIL_RCPT, r); curl_easy_setopt(c, CURLOPT_UPLOAD, 1L); curl_easy_setopt(c, CURLOPT_READFUNCTION, read_cb); curl_easy_setopt(c, CURLOPT_READDATA, off); curl_easy_perform(c); curl_slist_free_all(r); curl_easy_cleanup(c); return 0; }完整版见 smtp-mail.c。验证方法开CURLOPT_VERBOSE后输出与命令行-v一致同样以250收尾。另注意 QUIT 在curl_easy_cleanup()执行时才发出同一句柄连发多封相当于复用连接闲置几分钟服务器会自行断开。 场景二存量邮箱整箱归档的正确姿势curl POP3 下载整个邮箱这一节解决“把服务器上遗留的存量邮件全部搬回本地”从查数量到整箱导出。POP3 的模型很直白URL 里带/N就是取第 N 封不带路径就是整箱拉。# 先看总数与体积输出形如 OK 25 messages 4418813 octets curl -sI pop3s://pop.example.com --user username:password # 只取第 7 封URL 里的 /7 等价于 RETR 7 命令 curl pop3s://pop.example.com/7 --user username:password -o msg7.eml # 整箱导出到本地归档文件逐封追加 curl pop3s://pop.example.com --user username:password -o inbox.mbox验证方法第一条直接打出带数量与字节数的OK行后两条生成文件打开 .eml 检查是否以完整头部开头。边界要记牢curl 只执行 RETR不会自动删信DELE搬走的邮件在服务器上原样留着归档完想清空服务器得另外发删除命令。libcurl 版本用自定义请求发 STAT六行就够输出同样是OK 25 messages ...那行完整写法见 pop3-stat.ccurl_easy_setopt(c, CURLOPT_URL, pop3s://pop.example.com); curl_easy_setopt(c, CURLOPT_USERNAME, username); curl_easy_setopt(c, CURLOPT_PASSWORD, password); curl_easy_setopt(c, CURLOPT_CUSTOMREQUEST, STAT); curl_easy_setopt(c, CURLOPT_NOBODY, 1L); curl_easy_perform(c);想取指定某封把 URL 改成pop3s://pop.example.com/7即可完整写法见 pop3-retr.c。️ 场景三远程查、搜、取邮件curl IMAP 搜索未读邮件这一节解决“不把所有邮件下回来就能对远程邮箱做查询、搜索、取信”核心套路只有一条URL 路径就是“目标邮箱 / 选择器”其余操作一律用-X透传原生命令。# 列出服务器上的全部邮箱 curl -s imaps://imap.example.com --user username:password -X LIST * # 看 INBOX 的总数与未读数 curl -s imaps://imap.example.com/INBOX --user username:password \ -X STATUS INBOX (MESSAGES UNSEEN) # 搜未读打出一串以空格分隔的序列号 curl -s imaps://imap.example.com/INBOX --user username:password -X SEARCH UNSEEN # 取第 3 封全文或只抓头部 curl imaps://imap.example.com/INBOX/3 --user username:password -o msg3.eml curl -s imaps://imap.example.com/INBOX --user username:password -X FETCH 3 BODY[HEADER]验证方法SEARCH 输出数字列表例如3 7 12可以直接拼进 FETCH 的序号位取正文STATUS 会给出 MESSAGES / UNSEEN 两个数字各一行。序列号还是 UID序列号跟着当前排序走一旦有新信插入后面的号全体漂移UID 是稳定标识。跨会话做批量操作时优先用 UIDURL 选择器写成;UID1的形式例如imaps://imap.example.com/INBOX/;UID1搜索与取信的完整写法分别见 imap-search.c 和 imap-fetch.c。️ 诊断速查邮件错误码对照与调试三板斧命令一报错先按这张表对因下药报错大概率原因处理CURLE_COULDNT_CONNECT(7)端口被防火墙拦了或端口写错先用nc host 端口验证通不通587/465、995、993 换着试CURLE_LOGIN_DENIED(67)密码错、禁止登录或要求应用专用密码换成专用密码重试CURLE_SSL_CONNECT_ERROR(35)TLS 握手失败协议版本或 ALPN 对不上-v看卡在哪一步升级 curl 或改走隐式 TLS 端口CURLE_SSL_CACERT(60)本地不信任服务器证书--cacert或CURLOPT_CAINFO指定企业 CA 包CURLE_OPERATION_TIMEDOUT(28)服务器响应慢或被限流CURLOPT_CONNECTTIMEOUT与CURLOPT_TIMEOUT分开设置别指望一个值兜底调试三板斧命令行加-v每条命令与应答逐行可见库接口把CURLOPT_VERBOSE设成1L拿到同样的输出需要按行分流时挂CURLOPT_DEBUGFUNCTION回调里靠CURLINFO_HEADER_IN/CURLINFO_DATA_IN区分命令应答与邮件正文。 上生产前的最后核对交付前把这六项逐条过一遍正文文件是完整 MIME 文本头部 空行 正文了吗curl 不会替你补 Subject。认证流量走 TLS 了吗smtps://或--ssl-reqd至少占一个。发件地址带了尖括号addr吗细节见 CURLOPT_MAIL_FROM自动回复场景考虑空发件人避免回信循环。IMAP 批量操作用的是 UID 还是序列号序列号跨会话会漂移选 UID。理解 QUIT 的时机了吗它随curl_easy_cleanup()才发出句柄可复用连发多封闲置几分钟会被服务器断开。curl 版本够新吗curl --version输出里要有 SMTP / POP3 / IMAP 字样能力起点是 7.21。【免费下载链接】Awesome-Chinese-LLM整理开源的中文大语言模型以规模较小、可私有化部署、训练成本较低的模型为主包括底座模型垂直领域微调及应用数据集与教程等。项目地址: https://gitcode.com/GitHub_Trending/aw/Awesome-Chinese-LLM创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考