c语言socket/smtp 邮件 附件,SMTP邮件传输协议发送邮件和附件 1

在以前接触的项目中,一直都是在做网站时用到了发送mail 的功能,在asp 和.net 中都有相关的发送mail 的类,

实现起来非常简单。最近这段时间因工作需要在C++ 中使用发送mail

的功能,上网搜了一大堆资料,终于得以实现,总结自己开发过程中碰到的一些问题,希望对需的人有所帮助, 由于能力有限,

文中不免有些误解之处, 望大家能指正!!

其实,使用C++ 发送mail 也是很简的事, 只需要了解一点SMTP 协议和socket 编程就OK 了,

网络上也有很多高人写好的mail 类源码,有兴趣的朋友可以下载看看.

1. SMTP 常用命令简介

1). SMTP 常用命令

HELO/EHLO 向服务器标识用户身份

MAIL 初始化邮件传输

mail from:

RCPT 标识单个的邮件接收人;常在MAIL 命令后面

可有多个rcpt to:

DATA 在单个或多个RCPT 命令后,表示所有的邮件接收人已标识,并初始化数据传输,以. 结束。

VRFY 用于验证指定的用户/ 邮箱是否存在;由于安全方面的原因,服务器常禁止此命令

EXPN 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用

HELP 查询服务器支持什么命令

NOOP 无操作,服务器应响应OK

QUIT 结束会话

RSET 重置会话,当前传输被取消

如你对SMTP 命令不了解,可以用telnet 命令登陆到smtp 服务器用help 命令进行查看:

Normal 0 7.8 磅 0 2 false false false

MicrosoftInternetExplorer4

220 tdcsw.maintek.corpnet.asus ESMTP Sendmail 8.13.8/8.13.8; Sat, 9

Jan 2010 10:

45:09 +0800

help

214-2.0.0 This is sendmail

214-2.0.0 Topics:

214-2.0.0 HELO EHLO MAIL RCPT DATA

214-2.0.0 RSET NOOP QUIT HELP VRFY

214-2.0.0 EXPN VERB ETRN DSN AUTH

214-2.0.0 STARTTLS

214-2.0.0 For more info use "HELP ".

214-2.0.0 To report bugs in the implementation see

214-2.0.0 http://www.sendmail.org/email-addresses.html

214-2.0.0 For local information send email to Postmaster at your

site.

214 2.0.0 End of HELP info

2).SMTP 返回码含义

* 邮件服务返回代码含义

* 500 格式错误,命令不可识别(此错误也包括命令行过长)

* 501 参数格式错误

* 502 命令不可实现

* 503 错误的命令序列

* 504 命令参数不可实现

* 211 系统状态或系统帮助响应

* 214 帮助信息

* 220 服务就绪

* 221 服务关闭传输信道

* 421 服务未就绪,关闭传输信道(当必须关闭时,此应答可以作为对任何命令的响应)

* 250 要求的邮件操作完成

* 251 用户非本地,将转发向

* 450 要求的邮件操作未完成,邮箱不可用(例如,邮箱忙)

* 550 要求的邮件操作未完成,邮箱不可用(例如,邮箱未找到,或不可访问)

* 451 放弃要求的操作;处理过程中出错

* 551 用户非本地,请尝试

* 452 系统存储不足,要求的操作未执行

* 552 过量的存储分配,要求的操作未执行

* 553 邮箱名不可用,要求的操作未执行(例如邮箱格式错误)

* 354 开始邮件输入,以.

结束

* 554 操作失败

* 535 用户验证失败

* 235 用户验证成功

* 334 等待用户输入验证信息 for next

connection>;

3) SMTP 命令应用

我们下需使用telnet 命令实现smtp 邮件的发送,具体操作如下:

220 tdcsw.com ESMTP Sendmail 8.13.8/8.13.8; Wed, 23 Dec 2009

18

:18:18 +0800

HELO tdcsw

250 tdcsw.com Hello x-128-101-1-240.ahc.umn.edu [128.101.1.240],

pleased to meet you

MAIL FROM:lily@tdcsw.com

250 2.1.0 lily@tdcsw.com... Sender ok

RCPR TO:sam@163.com

250 2.1.5 carven@tdcsw.pegatroncorp.com... Recipient

ok

DATA

354 Enter mail, end with "." on a line by itself

SUBJECT:HELLO

HI:

HAR are you?

.

250 2.0.0 nBNAIIG4000507 Message accepted for

delivery

quit

221 2.0.0 tdcsw.maintek.corpnet.asus closing

connection

Connection to host lost.

2. 用C++ 实现Mail 发送

为了便于理解, 在此就不封装Mail 类了, 而是以过程式函数方式给出.

1). 首先需要建立TCP 套接字, 连接端口依服务器而定,SMTP 服务默认端口为25, 我们以

默认端口为例

WSADATA wsaData;

int SockFD;

WSAStartup(MAKEWORD(2,2), &wsaData);

SockFD = socket(AF_INET, SOCK_STREAM,

IPPROTO_TCP);

ServAddr.sin_family = AF_INET;

ServAddr.sin_addr.s_addr = inet_addr

(“192.168.1.1”); //192.168.1.1 为服务器地址

ServAddr.sin_port = htons(25);

connect(SockFD, (struct sockaddr *)&ServAddr,

sizeof(ServAddr));

2). 发送SMTP 命令及数据

const char HEADER[] = "HELO smtpSrv\r\n"

"MAIL FROM:

sender@126.com\r\n"

"RCPT TO:

recv@gmail.com\r\n"

"DATA\r\n"

"FROM:

sender@126.com\r\n"

"TO:

recv@gmail.com\r\n"

"SUBJECT: this is a

test\r\n"

"Date: Fri, 8 Jan 2010

16:12:30\r\n"

"X-Mailer: shadowstar's mailer\r\n"

"MIME-Version:

1.0\r\n"

"Content-type:

text/plain\r\n\r\n";

//send HEADER

send(SockFD, HEADER, strlen(HEADER), 0);

const char CONTENT[]="this is content.\r\n";

//send CONTENT

send(SockFD, CONTENT, strlen(CONTENT), 0);

send(SockFD, ".\r\n", strlen(".\r\n"),

0); //end

send(SockFD, "QUIT\r\n", strlen("QUIT\r\n"), 0);

//quit

mail 发送的功能基本上就完成了, 当然, 如果是应用的话还是需要很多改动的地方的,

比如说添加附件等.

3). 附件功能

要使用SMTP 发送附件, 需要对SMTP 头信息进行说明, 改变Content-type 及为每一段正文添加BOUNDARY 名,

示例如下:

"DATA\r\n"

"FROM:

sender@126.com\r\n"

"TO:

recv@gmail.com\r\n"

"SUBJECT: this is a

test\r\n"

"Date: Fri, 8 Jan 2010

16:12:30\r\n"

"X-Mailer: shadowstar's mailer\r\n"

"MIME-Version:

1.0\r\n"

"Content-type: multipart/mixed;

boundary="#BOUNDARY#"\r\n\r\n";

// 正文

"--#BOUNDARY#\r\n"

"Content-Type: text/plain;

charset=gb2312\r\n"

"Content-Transfer-Encoding:

quoted-printable\r\n"

邮件正文……….

// 附件

"\r\n--#BOUNDARY#\r\n"

"Content-Type:

application/octet-stream; name=att.txt\r\n"

"Content-Disposition:

attachment; filename=att.txt\r\n"

"Content-Transfer-Encoding:

base64\r\n"

"\r\n"

附件正信息(base64 编码)…..

Base64 编码函数在网络上很容易找到, 这里就不给出源码了, 如需要支持HTML 格式而又不知道如何写这些头信息,

可以用outlook 或foxmail 写一封支持HTML 格式的mail, 查看其原文信息,

依照相同的格式发送就行了.

4). 实现抄送及密送

在SMTP 命令集中并没有RCPT CC 或RCPT BCC 相关命令,

那要如何来实现抄送和密送功能呢?

在网络上找到这样一句话: “ 所有的接收者协商都通过RCPT TO 命令来实现,如果是BCC

,则协商发送后在对方接收时被删掉信封接收者”, 开始一直不明白这句话是什么意思? 后来通看查看foxmail

的邮件原文发现:

Date: Wed, 6 Jan 2010 12:11:48 +0800

From: "carven_li" < carven_li @smtp.com>

To: "carven"

Cc: "sam" ,

"yoyo"

BCC: "clara"

Subject: t

X-mailer: Foxmail 5.0 [cn]

Mime-Version: 1.0

Content-Type: multipart/mixed;

boundary="=====001_Dragon237244850520_====="

才恍然大悟, 所谓的” 协商” 应该就是指发送方在Data 中指定哪些为CC, 哪些为BCC, 默认情况下什么都不写,

只发送第一个RCPT TO 的mail, 其他的都被过滤掉.

主要功能: 1、可以发送附件邮件附件可以是多个,附件大小限制由发送方服务器而定,暂未测试具体为多少MB 2、邮件内容主题可以是空,但当有附件时,主题取第一个附件的文件名(不含扩展名) 3、密码验证均为base64加密 4、邮件正文附件的数据传送方式,均为base64 5、自动解析发件箱的SMTP服务器 压缩包文件简介: base.c:包含一些基本的函数,其中有一些在此程序中并未用到,只要使用了其中的base64加密算法 mail.c:包含邮件发送、数据读取、编码转换、smtp服务器连接、ip解析等函数 mailsend.c:包含main的c源文件,mail.exe则是根据mailsend.c、mail.c、base.c编译成的,具体编译方 法可参考makefile libbase.a:make之后生成的静态库 moontalk.cfg:base.c用到的配置文件,可能没用,放在这里进攻阅读参考 mail.cfg:自定义用户的配置文件,可用可不用,用作读代码的参考 mail.exe:邮件发送的执行文件,仅有命令行模式完善了,逐步输入(直接双击)的方式还不完善 b64.exe:base64加密解密的小工具,仅供参考,mail.cfg中用到密码的地方,可以使这个工具得到。 makefile:工程编译链接文件 注意:在本地使用mingw环境开发,遵循ANSI C标准,本地有系统的工程库,但是上传的时候,把这些文件 都放在一起了,可以先参考makefile进行工程调整,如果有任何问题,请发送到邮箱moontalk@yeah.net, 技术交流,不胜感激。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页
评论
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值