基于ESMTP的水文数据共享方法设计与实现

(整期优先)网络出版时间:2019-10-19
/ 3
摘 要 针对水利部门数据共享的高成本、低效率现状,提出一种通过email方式进行水文数据共享的方法。通过对ESMTP和POP3协议的应用,发送方将数据打包作为邮件的附件发送,接收方解析邮件,从而实现数据共享。该方法灵活方便,运行成本低。本文对协议进行了简单说明,同时对数据交换流程和实现类图进行了详细说明。

关键词 水文数据共享,ESMTP,POP3


0 引言

当前,水利信息化正在水利行业大力推行,其中水文数据的共享是水资源管理以及防洪抗灾等决策支持的核心。由于水利部门管辖流域分布广,各水文管理单位地域分散,管理机制多是采用集中-分散方式。管理站采集数据后传送给各个分中心,再由分中心将信息汇总后发送给管理局(或水利厅),使得管理局(或水利厅)能对管辖范围的水情信息进行整体把握,做出决策分析;此外,因为河流之间的联动关系,各分中心、管理站之间也需要相互通信,因此水文信息的互传及共享十分必要。

目前水文信息的互传及共享采用的方式主要有以下三种:1,电话(传真);2,公用通信信道;3,VPN(或网站)进行数据共享。但这三种方式有其明显的不足之处:电话(传真)方式需要人工参与,限制了工作人员的工作范围和处理事情的灵活性,而且需要接收方人工录入数据,这样效率很低且缺乏实时性。公用通信信道方式通常利用PSTN、GSM、GPRS等进行数据传输,这种方法传送的数据量受限且运行费用较高。通过VPN(或网站)进行数据共享,这种方式相对于前两种而言,真正实现了信息化,但建立VPN或网站都需要较高的投资和后期高昂的维护费用,这阻碍了它的广泛应用及推广。

为了弥补上述方法的不足,本文提出了基于email方式的水文数据共享的方法,通过邮件的收发,网络协议身份验证来实现信息的互传,实现无人工参与的数据共享。该方法简单、高效,只要能上网,不需要额外的系统维护成本,对于大多经济还不发达的水利单位具有实用性。

1 邮件收发协议简介

1.1 POP3协议

POP适用于C/S结构的脱机模型的电子邮件协议,目前已发展到第三版,称POP3。

在POP3协议中有三种状态:认可状态,处理状态,和更新状态。当客户机与服务器建立联系时,一旦客户机提供了自己身份并成功确认,即由认可状态转入处理状态,在完成相应的操作后客户机发出QUIT命令,则进入更新状态,更新之后重返认可状态。

一般情况下,大多数现有的POP3客户与服务器执行采用ASCII明文发送用户名和口令,在认可状态等待客户连接的情况下,客户发出连接,并由命令USER/PASS对在网络上发送明文用户名和口令给服务器进行身份确认。一旦确认成功,便转入处理状态。

1.2 ESMTP协议

ESMTP英文全称是“Extended SMTP”,是对SMTP协议的扩展,为了防止垃圾邮件的泛滥,采用了身份验证机制。在登陆服务器后需经过身份验证才能发信。其他部分同SMTP协议基本一样。命令AUTH LOGIN表示开始身份验证,然后是用户名和密码的验证。用户名和密码都是使用Base64编码。

1.2.1 SMTP协议:

SMTP称为简单邮件传输协议(Simple Mail Transfer Protocol),目标是向用户提供高效、可靠的邮件传输。SMTP的一个重要特点是它能够在传送中接力传送邮件,即邮件可以通过不同网络上的主机接力式传送。工作在两种情况下:一是电子邮件从客户机传输到服务器;二是从某一个服务器传输到另一个服务器。SMTP是个请求/响应协议,它监听25号端口,用于接收用户的Mail请求,并与远端Mail服务器建立SMTP连接。客户端向服务器发送请求命令,服务器向客户端返回一些响应信息。命令和响应都是基于ASCII文本,并以CR和LF符结束。响应包括一个表示返回状态的三位数字代码。

1.2.2 Base64编码:

由于历史原因,Email只被允许传送ASCII字符,即一个8位字节的低7位。因此,如果您发送了一封带有非ASCII字符(即字节的最高位是1)的Email通过有“历史问题”的网关时就可能会出现问题。网关可能会把最高位置为0而产生错误。基于以上的一些主要原因产生了Base64编码。

Base64编码的思想是采用64个基本的ASCII码字符对数据进行重新编码。它将需要编码的数据拆分成字节数组。以3个字节为一组。按顺序排列24位数据,再把这24位数据分成4组,即每组6位。再在每组的最高位前补两个0凑足一个字节。这样就把一个3字节为一组的数据重新编码成了4个字节。当所要编码的数据的字节数不是3的整倍数,也就是说在分组时最后一组不够3个字节。这时在最后一组填充1到2个0字节。并在最后编码完成后在结尾添加1到2个“=”。

2 水文信息共享系统实现

该系统通过网络邮件收发协议进行水文信息的传送。从信息保密的角度出发,发送协议我们采用具有身份验证机制的ESMTP协议;从信息可读性角度出发,即信息编码方式的限制,我们通过Base64编码进行解决;接收采用通用的POP3协议完成。

2.1 数据交换流程

当分中心需要将信息上报给管理处时,需要先设置邮件发送端口号以及邮件服务器,接着验证用户身份,然后是发送信息的添加和发送;接收方利用POP3协议到邮件服务器上进行下载,其中关键是附件的处理,当信息从邮件服务器中下载到接收方,则完成了一次信息交换。

1055386012.jpg

图1 数据交换示意图

从上图中可以把整个数据交换流程划分为三个部分:邮件发送,邮件接收和邮件处理。

1)邮件发送:把邮件从本地发送到邮件服务器。

首先,设置邮件发送的端口号和邮件服务器;进行服务器连接;

其次,将用户名和密码经过Base64编码,并且发送进行验证;

最后,邮件发送。

2)邮件接收:把邮件从服务器下载到本地并处理附件。

主要应用POP3协议将邮件从服务器进行邮件下载。其主要流程如图3所示:

1055396776.jpg

图2 发邮件流程图

首先,设置邮件接收端口号和下载邮件服务器;然后进行服务器连接;

其次,用户名和密码检验;

最后,邮件接收和附件处理。

1055397783.jpg

图3 收邮件流程图

3)邮件处理:构建和分析邮件的各个部件(邮件头,邮件体,附件等)。

该部分为整个系统实现的重点也是关键。它主要完成邮件体的生成、附件添加、以及接收邮件后邮件的解析和附件的处理等。

邮件的生成主要通过CMimeMessage、CMimeBody、CMimeHeader类。首先创建CMimeField类创建邮件项列表,然后CMimeHeader进行邮件的头部的生成,并存放到邮件项列表中;邮件体通过CMimeBody进行创建,加载附件,最后再调用CMimeMessage类构成邮件;实现代码如下:

CMimeMessage mail;

//设置邮件各项的值

mail.SetFrom(MailAddress);

mail.SetTo(DestinationAddress);

mail.SetSubject("邮件主题");

mail.SetDate();

mail.SetVersion();

mail.SetContentType("multipart/mixed");

mail.SetBoundary();

//创建邮件体

CMimeBody* pBp;

pBp = mail.CreatePart();

pBp->SetText("数据见附件");

pBp = mail.CreatePart();

//添加附件

pBp->SetDescription("attachment");

pBp->SetTransferEncoding("base64");

pBp->ReadFromFile("附件");

1055394237.jpg


图4 邮件收发类图


邮件解析主要实现邮件附件的处理,它通过定义中间文档将附件拷贝到内存当中,然后再从内存中将数据读出,然后以与邮件名同名的文件将附件存放到用户设定的目录下;实现代码如下:

CStdioFile File;

File.Open("a.txt",CFile::modeCreate|CFile::modeWrite);

LONG size = 0,nsize =0;

//接受邮件到文件

while(size <= lSize )

{

//接受邮件

nsize=m_wsSocket.Receive(buf,10240);

size =size + nsize;

File.Write(buf,nsize);

}

File.Flush();

File.Close();

//打开接收到的文件

File.Open("a.txt",CFile::modeRead);

//得到文件的大小

LONG FileSize=File.GetLength();

//建立缓冲区来存放读取文件的内容

char* pBuff = new char[FileSize];

File.Read(pBuff,size); //读取文件到缓冲区

File.Close(); //关闭文件

File.Remove("a.txt");

CMimeMessage mail;

mail.Load(pBuff,size);

CMimeBody::CBodyList bodies; // 定义变量

Int nCount=mail.GetBodyPartList(bodies);

CMimeBody::CBodyList::const_iterator it;

//获得附件

for (it=bodies.begin(); it!=bodies.end(); it++)

{

CMimeBody* pBP = *it;

if (pBP->IsAttachment())

{

//获得附件名

string strName = pBP->GetName();

//存储附件到当前目录

pBP->WriteToFile(FilePath+strName.c_str());

}

}

delete pBuff; //删除缓冲区

3 数据交换类图及其实现

该系统采用Visual C++6.0进行开发,将数据交换流程中三个主要部分封装为标准动态链接库。该模块具有通用性,可应用于需要进行数据交换和共享的系统。

从图4中可以看出通过CMimeHeader,CMimeBody和CMimeMessage主要用于邮件体的生成和解析;CSmtp类用于邮件发送;CPop3用于邮件接收。

4 结语

基于Email方式的水文数据共享系统的设计和开发为目前水文数据的互传和共享提供了一种新的方式,该方法高效、简单易行,只要开通了Internet网络即可应用,无运行维护费用。目前该系统在都江堰灌区东风渠管理处应用良好。

参考文献

[1] 潘爱民译. Visual C++技术内幕(第4版)[M]. 北京:清华大学出版社,2004

[2] 汪晓平,钟军. Visual C++网络通信协议分析与应用实现[M]. 北京:人民邮电出版社,2003

[3] 张建云,姚永熙,唐镇松. 我国水文自动测报系统的发展与探讨[J]. 水文,2006,26(3):53-56

[4] 梁家志,刘志雨. 中国水文情报预报的现状及展望[J]. 水文,2006,26(3):57-60

[5] 李彬,奚士佳 .基于GPRS+WEB灌区水文信息采集系统[J]. 中国农村水利水电,2006(2):7-9