电费代缴系统.docx
《电费代缴系统.docx》由会员分享,可在线阅读,更多相关《电费代缴系统.docx(44页珍藏版)》请在冰点文库上搜索。
电费代缴系统
河南城建学院
《Linux操作系统》课程设计报告
题目:
电费代缴系统
姓名:
2011年09月08日
前言
近年来,随着中国市场经济,科学技术的高速发展,传统的手工操作系统为主的电费缴纳的管理方式,因其信息反应慢,工作效率低,管理质量差,备受广大服务者争议。
在计算机信息技术飞速发展与广泛应用的今天,这种落后的管理方式与时代的步伐已显得格格不入,对电费缴纳系统实现智能化,信息管理化,是信息时代对现代社会电费管理工作提出的严峻要求,社会需要方便和快捷的缴费方式。
诸如我们交纳电费,传统的方式是大家要去指定代收电费点缴纳费用。
而代收的电费最终汇总到电力厂。
但是这样产生不少麻烦事:
电力厂要在不同地区设置电费代收点,用电客户要去代售点才能交纳电费满足日常电力所需。
这些都浪费了我们的体力时间和精力。
为方便客户缴费,不断拓宽缴费渠道,电业局不仅在城区和各供电所设立缴费营业场所,推行电费充值卡,还与各大主要银行共同合作推行银行实时代扣代缴电费业务。
电力客户不仅可以定时去银行续交电费,还可以存入多余的钱以防电力超支。
在电费账户中余款不够缴交当期电费时,银行将对客户账户中储蓄的电费余额进行扣款,这样电业局不仅减少了欠费,又降低了电费风险,有效提高了电费回收率,并且为客户节省了欠费违约金的支出。
该系统投入后,电力客户可选择在目前已与电业局联网的建行和兴业银行所属任一营业网点办理电费的实时查询、现金缴费、实时划转、储蓄代扣等事宜。
这将为我们的生活提供极大的便利。
为了是电费管理更加科学,更加严谨,同时更具有操作性,节省操作人员的劳动,电费缴纳系统必须与先进技术相结合,应用先进的网络管理技术来操作电费管理系统,从而使其为人们提供更方便,更快捷的电费管理服务。
目录
一、系统环境-4-
1、硬件环境:
-4-
2、软件环境-4-
二、设计目的及其要求-4-
1、设计目的-4-
2、设计要求-5-
三、总体设计-5-
1基本功能:
-6-
2总体设计流程图如下:
-7-
四、详细设计-8-
1:
客户端模块:
-8-
2:
信息通讯模块:
-8-
3:
中间件模块:
-10-
4:
服务器端模块:
-10-
5:
客户端,中间件和服务器联系-10-
五、调试与测试-11-
1.调试方法-11-
2.测试结果分析及讨论-11-
六、遇到的问题及解决方法-14-
七、源程序清单-15-
1.数据库代码-15-
2.服务器代码-16-
3.中间件程序-23-
4.客户端程序-27-
八、心得体会-31-
九、参考文献-32-
一、系统环境
1、硬件环境:
Pentium(R)4cpu2.08GHz,224MB内存
2、软件环境
RedhatLinuxmysql、Window操作系统、Linux虚拟机、mysql数据库C++编译器、Vi编辑器、文字处理软件Office、其他辅助软件。
服务器数据库要求使用Linux提供的免费的MySQL。
开发时主要用到C访问MySql的接口程序MySqlCAPI。
此系统利用Linux系统提供的Socket库和MySOL数据库在网络底层开发交易性中间件,同时简要介绍了客户端和服务器的工作模式。
采用“客户端—中间件—服务器”模式,其中主要包括三大部分:
客户端(client),中间件(middlewar)和服务器端(server)。
客户端主要实现用户管理、查询、缴费等功能;中间件要完成与客户要求相符的功能—是本地的本地处理,否则发往服务器端——接受客户端数据,组织服务器端所需数据,重组服务端返回数据,并返回给客户方;服务器端(Server)主要实现客户端或中间件提出的业务请求并做好留迹工作。
二、设计目的及其要求
1、设计目的
本设计的目的是使参与设计者掌握利用软件工程的思想方法和TCP/IP设计出用于不同行业和部门间的通讯转发或协议转换软件—中间件,尤其掌握这种设计的思想和方法。
在很多场合中间件部分是必须的,因为在不同的行业的网络是不允许直通的。
这里有政策的因素,有制度的要求,也有技术的成份。
对电费查询与缴费业务进行了系统全面的分析研究。
针对现有系统中实时性不足而造成用户欠费太多使公司企业蒙受损失的问题。
采用开发工具Linux+Mysql进行系统设计。
设计系统能够提供对点费信息输入、查询、编辑、自动计算出电费的各项合计数据;可自主设定条件从而达到数据的多角度查询功能。
2、设计要求
(1)客户端
客户端程序可命名为client,要求带有两个命令行参数一个是服务(自己定义,并保存在/etc/services中,比如mysvr15678),另一个是目的主机(自己定义,并保存在/etc/hosts内,也可使用DNS来解析),缺省时为本机。
也可以使用配置文件取代命令行参数。
客户端至少要实现如下功能:
用户管理、查询、交费、网上缴费、撤销、留迹、本地业务统计。
(2)中间件
中间件程序命名为middleware,要带有4个参数,一个是用于服务器的服务(名字,与客户端同),第二个作为向电费服务器请求的服务(自己定义,并保存在/etc/services中,要区别于客户端,比如mysvr25679),第三个是向银行服务器请求的服务,第四个为目的主机(定义在/etc/hosts内),缺省时为本机。
也可以使用配置文件取代命令行参数。
中间件要完成与客户要求相符的功能:
是本地的本地处理,否则发往服务器方。
具体地是:
接收客户方数据;组织服务器方所需数据;重组服务方返回数据,并返回给客户方;留迹;本地业务统计。
(3)服务器
服务器程序可命名为server,要求带有一个服务参数。
也可以使用配置文件取代命令行参数。
银行服务器命名为bank,带有一个服务参数。
服务器方程序要完成客户端或中间件提出的业务请求,并做好留迹工作。
(4)留迹或log
留迹或log工作在客户端、中间件和服务器三方都要做,以供统计或核对使用。
客户端或中间件方可以使用文本文件或数据库,但在服务器方必须使用MySql数据库。
三、总体设计
本次设计的主要课题是:
电费代缴系统,采用开发工具Linux+Mysql进行系统设计。
设计系统能够提供对电费信息查询、缴纳处理、打印以及电费统计各明细项目的数据编辑,自动计算出电费的各项合计数据;可自主设定条件从而达到对电费数据的查询功能;处理交纳费用时的资金管理问题。
方便导入、导出数据及输出报表。
整个设计过程是基于C/S模式开发。
即采用客户端(Client)/服务器端(Server)模式。
以及中间件的开发和使用,这里的中间件是指交易型中间件。
交易型中间件是指用在不同行业、不同部门间的通讯转发和协议转换的软件,在不同的行业、不同的系统间提供通讯转发和协议转换的桥梁作用。
例如电子商务、银行代理业务软件等都是这种类型的软件。
本设计不是基于WEB的,不需要很多与WEB开发相关的知识,主要是利用UNIX系统提供的Socket库在网络底层,开发交易型中间件。
1基本功能:
1.1查询费用
出纳员登录系统,根据用户提供的电力号把“查询费用”指令存入缓冲区。
中间件检测到查询费用指令,把查询费用指令组成数据包发送到服务器中。
服务器从接收表中查询到“查询费用”指令,把查询费用指令填入数据库.得到查询费用指令后从主数据库查询用户的费用信息。
服务器把查询费用的结果返回中间件,确认信息后,中间件从接收表中检测返回结果并返回至客户端,并监控错误操作,若发生则返回错误代码。
服务器如果因错误没有得到查询结果,将返回结果即系统错误。
最后客户端、中间件以及服务器端都会写入日志文件留迹。
1.2缴纳费用
缴纳费用是可以是现金缴费和网上缴费。
客户要求缴纳费用时,出纳员将会选择缴纳费用命令,该命令存入中间件。
中间件检测到“缴纳费用”指令,把“缴纳费用”指令组成数据包放入缓冲区,然后发送给服务器。
服务器收到“缴纳费用”的指令后把“缴纳费用”指令填入数据库。
得到“缴纳费用”后从主数据库进行处理,并把数据库中所欠的费用扣除,结果填入数据库。
在确认无误后将结果返回给中间件。
中间件接到来自服务器的数据包后检测无误后发送给客户端,服务器将进行错误监控,如果因为错误没有得到结果,把返回结果“系统错误”填入发送错误信息给中间件,然后中间件把信息返回给用户。
最后客户端、中间件以及服务器端都会写入日志文件留迹,以备信息的更新。
1.3退出系统
客户端发送退出系统请求,经中间件确认,然后客户端退出系统并关闭连接。
2总体设计流程图如下:
四、详细设计
1:
客户端模块:
客户端即是用户与系统交互的接口,用户通过客户端发出数据请求,在本系统中,客户端完成用户请求数据的接受,与中间件建立连接,把客户的请求数据传送给中间件,中间件对用户的请求数据进行处理,把处理结果传送到服务端,又服务端从数据库中取出数据,通过客户端显示个用户。
本模块主要用到了C++语言的标准输入(scanf())输出函数(sprintf())几标准错误输出函数(stderr()),和Socket底层信息通讯所用到的Socket通讯模型。
2:
信息通讯模块:
本系统采用的基与TCP/IP模型的Socket()编程来完成客户端和服务器端以及客户端、服务器端与中间件之间的连接和数据通信,我们就使用Socket编程来建立网络连接。
在Socket通信中需要使用到下列的一些函数:
1)创建套接字—socket()
应用程序在使用套接字前,必须拥有一个套接字,系统调用socket()向应用程序提供创建套接字的手段。
int socket(int domain, int type,int protocol)
该调用要接收3个参数,根据这3个参数建立一个套接字,并将相应的资源分配给它,同时返回一个整型套接字号,只和一个特定的协议相联系。
实际上指定了相关五元组中的“协议”这一元。
domain(协议族):
AF_INET,AF_UNIX,AF_IPX,…
type(类型):
SOCK_STREAM,SOCK_DGRAM
protocol(协议):
0-让系统使用指定类型和协议族上的默认协议。
2)绑定本地地址—bind()
当一个套接字用socket()创建后,存在一个名字空间(地址族),但它没有被命名,bind()将套接字地址(包括本地主机地址和本地端口地址)与所创建的套接字号绑定起来,即将名字赋予套接字,以指定本地半相关。
其调用格式如下:
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
3)监听连接—listen()
此调用用于面向连接服务器,表明它愿意接收连接。
1isten()需在accept()之前调用,其调用格式如下:
int listen(int sockfd,int backlog)
sockfd:
是bind后的文件描述符.backlog:
设置请求排队的最大长度.当有多个客户端程序和服务端相连时, 使用这个表示可以介绍的排队长度.
4)connect
功能:
客户方调用发出的请求
用法:
intconnect(intsockfd,conststructctsockaddr*server_addr,socklen_taddrlen);
在面向连接的协议中,该调用导致本地系统和外部系统之间连接实际建立。
5)accept
服务器调用,从等待从编号为s的套接字上接受客户连接请求
用法:
intaccept(ints,structsockaddr*addr,socklen_taddrlen);
connect与accept的说明
调用accept()后,服务器等待从编号为s的套接字上接受客户连接请求,连接请求是由客户方的connect()调用发出的。
当有连接请求到达时,accept()调用将请求连接队列上的第一个客户方套接字地址及长度放入addr和addrlen,并创建一个与s有相同特性的新套接字号。
新的套接字可用于处理服务器并发请求。
6)数据传输:
send()/write与recv()/read()
当一个连接建立以后,就可以传输数据了。
常用的系统调用有send()和recv()。
send()调用用于在参数s指定的已连接的数据报或流套接字上发送输出数据,
7)地址转换
应用程序常常需要在点分十进制的IP与二进制形式IP间的转换。
以下函数可以实现这种转换:
intinet_aton(constchar*ddaddress,structin_addr*adress)
char*inet_ntoa(structin_addraddress);
unsignedlongintinet_addr(constchar*ddaddress);
8)关闭套接字:
close()
close()关闭套接字s,并释放分配给该套接字的资源;如果s涉及一个打开的TCP连接,则该连接被释放。
close()的调用格式如下:
intclose(ints);
关闭套接字有两个函数close和shutdown.用close时和我们关闭文件一样.。
TCP连接是双向的(是可读写的),当我们使用close时,会把读写通道都关闭,有时侯我们希望只关闭一个方向,这个时候我们可以使用shutdown.针对不同的howto,系统回采取不同的关闭方式。
3:
中间件模块:
当客户端上的应用程序需要从网络中某个节点处获取一定的数据或服务时,这些数据和服务可能处于一个运行着和客户端不同的硬、软件、网络或操作系统的平台上。
C/S应用程序中负责寻找数据的部分只需访问一个中间件系统,由中间件完成到网络中找到数据源或服务,进而实现传输客户请求、重组答复信息,最后将结果送回应用程序的任务。
4:
服务器端模块:
服务器端模块主要是为用户提供服务,通过不同客户端的数据请求,完成不同的逻辑操作,通过对请求数据的解析。
从而选择不同的服务,对数据库进行不用的操作,并将得到是结果数据反还给客户断程序。
5:
客户端,中间件和服务器联系
五、调试与测试
1.调试方法
(1)安装组件:
rpm–ivhmysql-devel*.rpm
(2).增加服务:
vi/etc/services
s1001/tcp
m1002/tcp
b1003/tcp
(3)连接数据库:
mysql(4)编译及运行服务器:
cc–osserver.c-L/usr/lib/mysql-lmysqlclient
./ss
(5)编译及运行中间件:
cc–omtestmid.c-L/usr/lib/mysql-lmysqlclient
./mmsblocalhost
(6)编译及运行银行服务器:
cc–obbank.c-L/usr/lib/mysql-lmysqlclient
./mmsblocalhost
2.测试结果分析及讨论
(1)建立数据库Electric_fee
(2)程序主界面
(3)返回结果信息
六、遇到的问题及解决方法
为期两周的课程设计对我来说确实是一大挑战。
在这期间遇到很多不会的知识点。
幸亏有诸多老师和同学的帮忙以及借助网络的功能,让我得以顺利的进行完这次课程设计。
这是我们第一次学习关于中间件的知识,对它的具体运行只是有一定程度的了解,不是很深刻,在设计中由于对Linux知识的掌握不好,导致初期进度是相当的慢,在开始的几天里差不多就没有什么进度,老师的两次视频讲解和给以一定的资料后,我们开始有了一点点的设计思路,设计过程中用到的知识不单单是课本上有的,还有的是课本上没介绍过的,因此这就需要我们多方的查阅资料和向老师请教。
以下是设计过程中遇到的问题及解决方法
(1)对Mysql数据库不够了解,对很多数据结构和算法也理解不够牢固,因此我们参考了《Linux+php+Mysql基础与提高》这本书,学到一些关于Mysql的基础知识,才使工作能顺利的进行下去。
(2)对套接字这样的概念不是很清楚,在老师的辅导和互联网的帮助下,了解了一些这方面的知识,才使我们的设计开展下来。
(3)以前对服务器,客户端只是了解理论知识,这次而要自己动手来开发服务器,这对我们来说,是一个巨大的挑战,服务器就是一个进程,确切的说是一个守候进程,要实现它的功能,是不容易的事情,你要学会套接字,地址转换,服务器相关的数据结构和算法才能进行开发和设计。
(4)还是很多基础的东西没有掌握好,基本的算法也没有完全掌握,参考了教科书的相关内容后,才开始了我们的课程设计。
(5)在数据库的编写时,很多要用到的数据类型而我们又没有学过的,只能借助互联网的强大功能了,由此,我们也学到了很多相关的知识。
七、源程序清单
1.数据库代码
createdatabaseElectric_fee;
useElectric_fee;
createtableusers(elec_idchar(20)primarykey,enamevarchar(20),addressvarchar(50));
createtableelectric(elec_idchar(20)primarykey,pricechar(4),balancechar(20),datevarchar(20));
createtablebank(b_idchar(20)notnullprimarykey,c_namechar(15)notnull,passwordchar(15),balancechar(20));
insertintobankvalues("0123456789","小蔡","123","1000.00");
insertintousers(elec_id,ename,address)values(1001,"小王","平顶山市湛河区沁园小区20号");
insertintousersvalues(1002,"小强","平顶山市湛河区沁园小区21号");
insertintousersvalues(1003,"小张","平顶山市新华区光明路10号");
insertintousersvalues(1004,"小李","平顶山市卫东区建设路125号");
insertintousersvalues(1005,"小米","平顶山市新城区明月路12号");
insertintousersvalues(1006,"小于","平顶山市新城区湖光花园100号");
insertintousersvalues(1007,"小朱","平顶山市新华区矿工路26号");
insertintousersvalues(1008,"小周","平顶山市卫东区建设路106号");
insertintousersvalues(1009,"王明","平顶山市湛河区沁园小区15号");
insertintousersvalues(1010,"李刚","平顶山市湛河区沁园小区19号");
insertintousersvalues(1011,"周涛","平顶山市卫东区建设路123号");
insertintousersvalues(1012,"于阳","平顶山市卫东区建设路146号");
insertintousersvalues(1013,"张风","平顶山市新城区明月路111号");
insertintoelectricvalues(1001,5.00,0,"20110907");
insertintoelectricvalues(1002,5.00,0,"20110907");
insertintoelectricvalues(1003,5.00,0,"20110907");
insertintoelectricvalues(1004,5.00,0,"20110907");
insertintoelectricvalues(1005,5.00,0,"20110907");
insertintoelectricvalues(1006,5.00,0,"20110907");
insertintoelectricvalues(1007,5.00,0,"20110907");
insertintoelectricvalues(1008,5.00,0,"20110907");
insertintoelectricvalues(1009,5.00,0,"20110907");
insertintoelectricvalues(1010,5.00,0,"20110907");
insertintoelectricvalues(1011,5.00,0,"20110907");
insertintoelectricvalues(1012,5.00,0,"20110907");
insertintoelectricvalues(1013,5.00,0,"20110907");
2.服务器代码
Server.c
#include
#include
#include
#include
#include
#include
#include
#include
#definerec_length20
#defineMAXDATASIZE4096
voidgetm(char*buf,charresult[][50])
{
chartemp[100]={0};
intk=0,n=0,i=0;
for(k=0;k{
if(buf[k]=='|'){temp[n]='\0';printf("%s\n",temp);strcpy(result[i],temp);i++;n=0;}
elsetemp[n++]=buf[k];
}
temp[n]='\0';
strcpy(result[i],temp);
}
intopdb(char*cmd,char*p,intflag)//操作数据库函数
{
MYSQLmysql;
MYSQL_RES*result;
MYSQL_ROWrow;
inti,j,n=0;
charbuf[1280];
mysql_init(&mysql);
printf("SQL语句:
%s\n",cmd);
mysql_real_connect(&mysql,"localhost","root",0,"Electric_fee",0,NULL,0);
printf("root成功连接数据库!
\n");
if(mysql_query(&mysql,cmd)!
=0){printf("操作数据库失败!
\n");return-1;}
if(flag==1)
{