嵌入式系统中SMTP协议的通讯实现
摘要:本文介绍了在网络时代的嵌入式系统发展状况,结合网络协议中SMTP|0">SMTP协议自身的特点及其应用,提出了在嵌入式系统中提供SMTP支持的具体流程和方法,然后给出了SMTP代理在嵌入式系统下的一个具体实现.
关键字:嵌入式系统 SMTP
引言
随着因特网技术的成熟,在以信息家电为代表的互联网时代嵌入式产品中SMTP协议得到广泛的应用。 SMTP 协议作为嵌入式领域中的客户机协议十分有用的原因就是可以被大量的现有的基础设施所支持。在嵌入式系统的角度上说,通过简单的SMTP协议工作可以异步的传输数据,数据以email的形式通过MTA进行传输,主要的工作交给SMTP基础设施去接管,减少在嵌入式系统中进行同步数据传输时带来的运行开销。并且通过使用MIME还可以扩展单一的文本数据的传输方式,传输各种包括音频,视频或静止图象等丰富的多媒体数据。同时,在SMTP客户和服务器中通过email的方式进行通讯还可以作为工具来对远程设备更新命令传输和响应。
1.SMTP协议的通讯模型和会话流程:
SMTP协议通讯模型
SMTP协议是TCP/IP协议族中的一员,其通信模型并不复杂,适合于工作在嵌入式系统的环境下。它的主要工作集中在发送SMTP和接收SMTP上:首先针对用户发出的邮件请求,由发送SMTP建立一条连接到接收SMTP的双工通讯链路,这里的接收SMTP是相对于发送SMTP而言的,实际上它既可以是最终的接收者也可以是中间传送者。发送SMTP负责向接收SMTP发送SMTP命令,而接收SMTP则负责接收并反馈应答。可大致用下面的通讯模型示意图来表示:
SMTP协议的命令和应答
从通讯模型可以看出SMTP协议在发送SMTP和接收SMTP之间的会话是靠发送SMTP的 SMTP命令和接收SMTP反馈的应答来完成的。在通讯链路建立后,SMTP客户端发送MAIL命令指令邮件发送者,若SMTP服务器此时可以接收邮件则作出OK的应答,然后SMTP客户端继续发出RCPT命令以确认邮件是否收到,如果接收到SMTP服务器端就作出OK的应答,否则就发出拒绝接收应答,但这并不会对整个邮件操作造成影响。双方如此反复多次,直至邮件处理完毕。SMTP协议共包含10个SMTP命令,主要命令有 HELO,MAIL FROM, RCPT TO,DATA,QUIT等,它们用来完成服务器端和客户端在进行数据传输正式开始前需要进行的同步。
2.SMTP服务器和SMTP客户之间的对话实例:
首先建立TCP连接,然后客户端发送HELO命令以标识发件人自己的身份,然后客户端发送MAIL命令,服务器端正希望以OK作为响应,表明准备接收。接下来客户端发送RCPT命令,以标识该电子邮件的计划接收人,可以有多个RCPT行,服务器端则表示是否愿意为收件人接受邮件 。在协商结束后发送邮件,用命令DATA发送,将输入内容一起发送出去。最后结束此次发送,用QUIT命令退出。
C: HELO emailserver.com
S: 250 emailserver.com hello ident::root@[192.168.2.121]
C: MAIL FROM:<tom@emailserver.com>
S: 250 <tom@emailserver.com> sender ok
C: RCPT TO:<peter@emailserver.com>
S: 250 <peter@emailserver.com> recipient ok
C: DATA
S: 354 Enter mail,end with "." on a line by itself
C:
C: Content-type: text/plain
C:
C: This is a test email
C:
C: .
S: 250 Message accepted for delivery
C: QUIT
S: 221 emailserver.com closing connection
3.SMTP客户端的实现:
在这里,本文只着重提供具体实现中的关键部分,其余部分可以很方便的实现,故不再多述。首先,定义通讯过程中使用的简化数据结构:
// Embedded SMTP Client header
Struct mailheader {
char subject[MAX_SUBJECT+1];
char sender[MAX_SEND+1];
char recipient[MAX_RCPT+1];
char contentType[MAX_CONTENT+1];
char *contents;
}
在这里可以看出来,结构 mailheader 的各个字段对应着运用 SMTP
然后,定义在客户端使用SMTP协议通讯的主函数 sendmail, 函数原型为:int sendmail(struct mailheader* mail) 下面是该函数的代码的主要部分:
int sendmail(struct mailheader) {
// local variables definition
int connfd, result, ret, goodMsg = 0;
struct sockaddr_in servaddr;
// set up socket connection routine
connfd = socket(AF_INET,SOCK_STREAM,0);
.....
result = connect(connfd,(struct sockaddr*)&servaddr,sizeof(servaddr);
do {
// Be sure to check each request and response for correct communication
// Look for initial salution
// Send HELO and await response
// Send MAIL FROM and await response
// Send RCPT TO and await response
// Send DATA and await response
// Send out mail contents
// Send QUIT and await response
} while(0);
close(connfd);
return (goodMsg);
}
- SIP协议简介(05-07)
- 嵌入式系统的定义与发展历史(11-15)
- 嵌入式系统亲密接触(11-22)
- 嵌入式系统设计中的USB OTG方案(02-01)
- 一个典型的嵌入式系统设计和实现 (02-02)
- DDR SDRAM在嵌入式系统中的应用(02-07)