校车订票系统报告_第1页
校车订票系统报告_第2页
校车订票系统报告_第3页
校车订票系统报告_第4页
校车订票系统报告_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

..《移动通信与无线网络》大作业报告校车订票系统课程:学校:组长:组员:完成时间:目录TOC\z\o"1-3"\u\h一需求分析⑺编制设计说明书。总体设计过程可分为两个主要阶段:<1>功能设计,确定车站售票系统的实现方案;结构设计,确定该软件的结构。功能设计是在需求分析的基础上进行的,这里所说的"功能"是泛指的,不仅指问题定义中列出的功能,还包括软件定义时确定的任何一个独立的数据加工或处理步骤,例如添加、删除、查询和各个特定功能的算法实现等。<2>结构设计,是将整个系统按照不同的功能和层次划分为一个个功能简单明确且相对独立的部分〔模块,每个模块实现系统的一项具体功能,自顶向下,逐步细化。结构设计是确定程序由哪些模块组成,以及这些模块之间的关系。1.1系统功能设计本系统分三个模块,登录功能模块;管理员功能模块,实现车票和车次管理;普通用户功能模块,实现车票和个人信息管理。校车车票网上订票系统简单、操作灵活、方便、反应快速、计算准确,系统运行稳定、安全可靠,而且有良好的交互界面,让使用者可以方便、快速地掌握。1.2系统的总体结构根据系统分析,按照结构化程序设计的要求得到了下面的系统功能模块图:删除车次发布车次删除车次发布车次更新车次管理员功能选择更新车次管理员功能选择校车消息推送消息校车消息推送消息天气信息天气信息校车票网上订票系统校车票网上订票系统修改信息修改信息修改信息修改信息账户重置账户重置普通用户功能选择普通用户功能选择查询信息车次查询查询信息车次查询时间查询时间查询车票管理车票管理预订车票退去车票退去车票图5校车车票网上订票系统总体功能图1.3子模块描述各个子模块描述如下:1.登录功能模块:打开手机应用程序,进入登录功能模块,选择登录身份区别是普通用户或是系统管理员。2.管理员功能模块:车次管理功能模块主要实现车次的添加、车次更新、删除等功能。同时为了更好的提供出行信息,管理员可以根据天气信息推荐学生注意天气的变化等信息,温馨地关心学生。3.普通用户功能模块:<1>查询功能模块:主要完成车票信息查询、订票信息查询等功能。<2>车票管理功能模块:主要完成校车车票的订票,退票等功能。<3>个人信息管理功能模块:主要完成个人信息的修改等功能。四视图设计1E-R图2数据流图数据流程图是以图形的方式表达在问题中信息的变换和传递过程。它把系统看成是由数据流联系的各种概念的组合,用分解及抽象手段来控制需求分析的复杂性,采用分层的数据流程图来表示一个复杂的系统。校车车票网上订票系统系统登录数据流图:开始开始登录登录身份识别身份识别管理员/普通用户管理员操作用户管理员操作用户结束结束图6校车车票网上订票系统登录管理数据流图校车车票网上订票系统车票查询数据流图:普通用户普通用户登录登录查询选择查询选择车次信息查询订票信息查询个人信息查询修改个人信息车次信息查询订票信息查询个人信息查询修改个人信息结束结束图7校车车票网上订票系统查询管理数据流图校车车票网上订票系统车次、车票、时间管理数据流图:图9校车车票网上订票系统车次、车票管理数据流图3程序描述3.1客户端程序本套校车车票订票系统软件的客户端应用程序以手机软件程序编写,客户使用手机安装下载通过互连网络对数据库进行访问,并完成客户端可以完成的功能。3.2服务器端程序本套校车车票订票系统软件的服务器端应用程序,在linux平台下编写前台控制软件,用电脑主机充当服务器,管理员通过使用该软件来进行对数据库中的数据进行管理。3.3后台数据库本套校车车票订票系统软件的后台数据库使用MySQL来搭建后台数据库服务器,用来存放所有的数据。4功能描述4.1整体流程设计校车订票系统管理员登陆用户登录用户注册前台浏览身份认证身份认证认证失败认证失败认证成功认证成功后台管理模块用户前台模块图10整体系统设计思路4.2客户端的主要功能3.2.1用户订票的全部过程用户登陆成功用户登陆成功查询车次查询余票

预定车票

注销退订车票用户中心图11用户订票流程图图12订票逻辑图图13历史订单查询及删除逻辑4.3服务器的主要功能管理员登陆成功管理员登陆成功用户管理校车管理订票管理帐号管理日志管理管理员信息用户信息校车安排表余票信息消息推送订票信息退票信息学生数据库系统日志注销图14管理员程序实现流程4.4软件时序图设计软件程序时,时序图包含如下的四个元素:1>对象,2>生命线,3>消息,4>激活。图14用户预订车票时序图图15用户退票时序图4.5数据库接口本套校车订票系统软件服务器端的程序是使用eclipse来编写完成,建立eclipse与数据库的连接使用了ADODB的对象来完成,每个模块中都使用了Recordset、Command、Connection的对象,因此在模块中对三者的对象进行定义<分别为:rs、cmd、cn>,并且将cn连接数据库的语句写好并打开连接,在其他的模块中共同调用这三个对象来对数据库进行操作。图16软件具体实现接口五程序实现1.1客户端通信方式有和Socket两种。<1>通信:连接使用的是"请求—响应方式",即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据<2>Socket通信:在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求图17TCP通信模型的Socket于是本设计选择安卓Socket编程方式实现:服务器端:首先声明一个ServerSocket对象并且指定端口号,然后调用Serversocket的accept<>方法接收客户端的数据,accept<>方法在没有数据进行接收的处于堵塞状态。一旦接收到数据,通过inputstream读取接收的数据客户端:创建一个Socket对象,指定服务器端的ip地址和端口通过inputstream读取数据,获取服务器发出的数据最后将要发送的数据写入到outputstream即可进行TCP协议的socket数据传输。天气预报的实现部分,通过资料查询,我们发现有如下免费天气预报获取途径,如下所示:Google的天气预报API中央气象台中国气象局WeatherWebService其中WebXml

天气预报Web服务,数据每2.5小时左右自动更新一次,准确可靠。包括340多个中国主要城市和60多个国外主要城市三日内的天气预报数据。于是我们选择这一资源进行天气信息的推送。1.2服务器在服务器上的程序由于要接受多个用户的请求,程序的灵活性和健壮性必须要得到保证,于是本设计采用多线程程序设计思想,对校车系统进行了一些测试。多线程程序有如下优点:1>线程间方便的通信机制2>提高应用程序响应3>使多CPU系统更加有效4>改善程序结构设计思路:多线程的程序结构能够极大的便利程序设计,本设计将整个系统进行功能模块的分解,使得每个功能模块独立不相关,每个模块占用一个线程,独立和协调地完成整个系统的功能,这种程序设计思路方便管理和增加新的功能,可扩展性强。多线程列表服务器是否可达预售期查询余票查询预定车票今日订单查询订单查询消息详细信息账号验证个人信息查询密码修改班车信息查询退票图18多线程划分列表事件监听方面,epoll

是Linux内核中的一种可扩展IO事件处理机制,最早在Linux2.5.44内核中引入,可被用于代替POSIXselect和poll系统调用,并且在具有大量应用程序请求时能够获得较好的性能,epoll与FreeBSD的kqueue类似,都向用户空间提供了自己的文件描述符来进行操作。epoll负责监听来自应用程序的TCP/IP请求,并反馈信息到手机应用端1.3加密与解密在与服务器之间的数据交互中,除了可以使用post请求来进行加密请求之外,我们可以使用常见的加密算法,对数据进行加密。本设计采用DES加密算法。DES<DataEncryptionStandard>,即数据加密标准,是一种使用密钥加密的块算法,DES算法的入口参数有三个:Key、Data、Mode。其中Key为7个字节的工作密钥;Data是要被加密或被解密的8个字节数据;Mode为DES的工作方式,分为:加密或解密。DES是一种对称的加密算法,加密和解密使用同一个密钥。本设计使用DES算法进行加密,采用的是CBC模式,填充方式采用PKCS5Padding。

CBC模式指的是加密块链模式,算法加入了初始向量。下面的代码就是获取一个初始向量,这种模式的特点是:

1>加密的密文长度为8个字节;2>当明文使用相同的密钥和初始向量的时候,CBC模式总是产生相同的密文;3>密文块不能再次排列;4>为避免相同的明文产生相同的密文,可以使用不同的初始化向量;5>一个错误发生以后,当前和以后的密文都会被影响。

在不同的平台上,只要能保证这几个参数的一致,就可以实现加密和解密的一致性:加密和解密的密钥一致;采用CBC模式的时候,要保证初始向量一致;采用相同的填充模式。六总结在现今移动互联网浪潮下,校车订票系统作为一个典型的应用,正在便利我们的生活,人们的生活越来越离不开手机,人们的大部分活动,交友,娱乐也越来越多依赖手机。关于手机APP的设计和用户需求分析,也给我们小组所有成员带来了许多思考。小组设计的初衷在于解决生活中的一些力所能及的事情,或许这些设计不算很完美,却锻炼了我们发现问题,解决问题,提出问题的能力,让我们在未来的科研路上,可以脚踏实地,少走弯路。本设计将校车订票系统分三部分进行,手机客户端,服务器端,数据库。手机客户端界面设计美观,操作简单方便;服务器端在笔记本电脑上,运行在Linux操作系统下,采用多线程框架编写程序,方便程序管理与更新。校车订票系统从功能上实现:服务端目前具备发布以及更新订票信息,注册帐号,管理数据库等功能;客户端上具备订票信息查询,余票查询,注册帐号,天气信息获取,预订车票以及退订车票等功能。 不过本设计还存在许多不足的地方,表现在如下二个方面:1>进度上:由于没有获取国科大学生的基本信息以及校车的真实信息,校车订票系统还未整体测试和完善。此外稳定性及流畅性各种方面都未获得验证。2>设计上:校车订票系统设计思路传统,创新上存在不足。附录服务器程序1.1数据库功能实现#include"btbs.h"#include<stdlib.h>#include<string.h>#include<stdio.h>#include<unistd.h>#include<errno.h>#include<sys/types.h>#include<sys/socket.h>#include<pthread.h>staticpthread_mutex_tmutex=PTHREAD_MUTEX_INITIALIZER;void*book_ticket<void*arg>{ if<arg==NULL> { returnNULL; } arg_attrarg_=*<arg_attr*>arg; MYSQLmy_connection; my_connection=*<arg_.my_connection>; intclient_fd=arg_.client_fd; intcmd[1024]={0}; charstudentId[20]={0}; charstartplace[50]={0}; charyear[6]={0}; charmonth[3]={0}; charday[4]={0}; charweekend[3]={0}; strcpy<cmd,arg_.cmd>; strcpy<studentId,arg_.op_cmd[0]>; strcpy<startplace,arg_.op_cmd[1]>; strcpy<year,arg_.op_cmd[2]>; strcpy<month,arg_.op_cmd[3]>; strcpy<day,arg_.op_cmd[4]>; strcpy<weekend,arg_.op_cmd[5]>; intretval; //mysql_query<arg_.my_connection,"setnames'utf8'">; retval=mysql_query<&my_connection,cmd>; printf<"%s\n",cmd>; if<!retval> { MYSQL_RES*res_ptr=mysql_use_result<&my_connection>; if<res_ptr> { MYSQL_ROWsqlrow=mysql_fetch_row<res_ptr>; if<sqlrow> { if<send<client_fd,"existed",sizeof<"existed">,0>==-1> { fprintf<stderr,"sendinbook_ticketfailed%s\n",strerror<errno>>; } } else { charcmd1[1024]={0}; charcmd2[1024]={0}; if<strcmp<startplace,"雁栖湖校区">==0&&strcmp<weekend,"0">==0> { sprintf<cmd1,"insertintoTicketsReservationvalues<'C1','%s','%s-%s-%s','07:20:00'>",studentId,year,month,day>; sprintf<cmd2,"updateTicketsLeftsetticketsno=ticketsno-1whereticketsno>0andbusno='C1'andbusdate='%s-%s-%s'",year,month,day>; } elseif<strcmp<startplace,"雁栖湖校区">==0&&strcmp<weekend,"1">==0> { sprintf<cmd1,"insertintoTicketsReservationvalues<'E1','%s','%s-%s-%s','07:20:00'>",studentId,year,month,day>; sprintf<cmd2,"updateTicketsLeftsetticketsno=ticketsno-1whereticketsno>0andbusno='E1'andbusdate='%s-%s-%s'",year,month,day>; } elseif<strcmp<startplace,"玉泉路校区">==0&&strcmp<weekend,"0">==0> { sprintf<cmd1,"insertintoTicketsReservationvalues<'C2','%s','%s-%s-%s','15:00:00'>",studentId,year,month,day>; sprintf<cmd2,"updateTicketsLeftsetticketsno=ticketsno-1whereticketsno>0andbusno='C2'andbusdate='%s-%s-%s'",year,month,day>; } else { sprintf<cmd1,"insertintoTicketsReservationvalues<'E2','%s','%s-%s-%s','18:00:00'>",studentId,year,month,day>; sprintf<cmd2,"updateTicketsLeftsetticketsno=ticketsno-1whereticketsno>0andbusno='E2'andbusdate='%s-%s-%s'",year,month,day>; } printf<"%s\n",cmd1>; printf<"%s\n",cmd2>; pthread_mutex_lock<&mutex>; mysql_query<&my_connection,cmd2>; pthread_mutex_unlock<&mutex>; if<mysql_affected_rows<&my_connection>> { mysql_query<&my_connection,cmd1>; if<send<client_fd,"True",sizeof<"True">,0>==-1> { fprintf<stderr,"sendinbook_ticketfailed%s\n",strerror<errno>>; } } else { if<send<client_fd,"False",sizeof<"False">,0>==-1> { fprintf<stderr,"sendinbook_ticketfailed%s\n",strerror<errno>>; } } } mysql_free_result<res_ptr>; } } else { fprintf<stderr,"book_ticketerror%d:%s\n",mysql_errno<&my_connection>,mysql_error<&my_connection>>; } close<client_fd>; returnNULL;}void*drop_ticket<void*arg>{ if<arg==NULL> { returnNULL; } arg_attrarg_=*<arg_attr*>arg; MYSQLmy_connection; my_connection=*<arg_.my_connection>; intclient_fd=arg_.client_fd; intcmd[1024]={0}; charstudentId[20]={0}; charstartplace[50]={0}; charyear[6]={0}; charmonth[3]={0}; charday[4]={0}; charweekend[3]={0}; strcpy<cmd,arg_.cmd>; strcpy<studentId,arg_.op_cmd[0]>; strcpy<startplace,arg_.op_cmd[1]>; strcpy<year,arg_.op_cmd[2]>; strcpy<month,arg_.op_cmd[3]>; strcpy<day,arg_.op_cmd[4]>; strcpy<weekend,arg_.op_cmd[5]>; intretval=mysql_query<&my_connection,cmd>; if<!retval> { if<mysql_affected_rows<&my_connection>> { charcmd[1024]={0}; sprintf<cmd,"updateTicketsLeftsetticketsno=ticketsno+1wherebusno=<selectbusnofromSchoolBuswherestartplace='%s'andweekend='%s'>andbusdate='%s-%s-%s'",startplace,weekend,year,month,day>; mysql_query<&my_connection,cmd>; if<mysql_affected_rows<&my_connection>> { if<send<client_fd,"True",sizeof<"True">,0>==-1> { fprintf<stderr,"sendindrop_ticketfailed%s\n",strerror<errno>>; } } else { printf<"updateindrop_ticketfailed\n">; } } } close<client_fd>; returnNULL;}void*check_account<void*arg>{ if<arg==NULL> { returnNULL; } arg_attrarg_=*<arg_attr*>arg; MYSQLmy_connection; my_connection=*<arg_.my_connection>; intclient_fd=arg_.client_fd; intcmd[1024]={0}; strcpy<cmd,arg_.cmd>; intretval; //mysql_query<arg_.my_connection,"setnames'utf8'">; retval=mysql_query<&my_connection,cmd>; printf<"%s\n",cmd>; if<!retval> { MYSQL_RES*res_ptr=mysql_use_result<&my_connection>; if<res_ptr> { MYSQL_ROWsqlrow=mysql_fetch_row<res_ptr>; if<sqlrow> { if<send<client_fd,"True",sizeof<"True">,0>==-1> { fprintf<stderr,"sendincheck_accountfailed%s\n",strerror<errno>>; } } else { if<send<client_fd,"False",sizeof<"False">,0>==-1> { fprintf<stderr,"sendincheck_accountfailed%s\n",strerror<errno>>; } } mysql_free_result<res_ptr>; } } else { fprintf<stderr,"check_accounterror%d:%s\n",mysql_errno<&my_connection>,mysql_error<&my_connection>>; } close<client_fd>; returnNULL;}void*modify_passwd<void*arg>{ if<arg==NULL> { returnNULL; } arg_attrarg_=*<arg_attr*>arg; MYSQLmy_connection; my_connection=*<arg_.my_connection>; intclient_fd=arg_.client_fd; intcmd[1024]={0}; strcpy<cmd,arg_.cmd>; intretval; //mysql_query<arg_.my_connection,"setnames'utf8'">; retval=mysql_query<&my_connection,cmd>; if<!retval> { if<mysql_affected_rows<&my_connection>> { if<send<client_fd,"True",sizeof<"True">,0>==-1> { fprintf<stderr,"sendinmodify_passwdfailed%s\n",strerror<errno>>; } } else { if<send<client_fd,"FALSE",sizeof<"FALSE">,0>==-1> { fprintf<stderr,"sendinmodify_passwdfailed%s\n",strerror<errno>>; } } } else { fprintf<stderr,"modify_passwderror%d:%s\n",mysql_errno<&my_connection>,mysql_error<&my_connection>>; if<send<client_fd,"FALSE",sizeof<"FALSE">,0>==-1> { fprintf<stderr,"sendinmodify_passwdfailed%s\n",strerror<errno>>; } } close<client_fd>; returnNULL;}void*query<void*arg>{ if<arg==NULL> { returnNULL; } arg_attrarg_=*<arg_attr*>arg; MYSQLmy_connection; my_connection=*<arg_.my_connection>; intclient_fd=arg_.client_fd; intcmd[1024]={0}; strcpy<cmd,arg_.cmd>; //sleep<10>; intretval; //mysql_query<arg_.my_connection,"setnames'utf8'">; retval=mysql_query<&my_connection,cmd>; if<!retval> { MYSQL_RES*res_ptr=mysql_use_result<&my_connection>; if<res_ptr> { MYSQL_ROWsqlrow; charbuf[4*1024]; memset<buf,0,sizeof<buf>>; while<<sqlrow=mysql_fetch_row<res_ptr>>> { unsignedintfield_count=0; while<field_count<mysql_field_count<&my_connection>> { if<!strcat<buf,sqlrow[field_count]>> { returnNULL; } //printf<"%s\n",sqlrow[field_count]>; if<field_count!=mysql_field_count<&my_connection>-1> { if<!strcat<buf,",">> { returnNULL; } } else { if<!strcat<buf,"#">> { returnNULL; } } field_count++; } } if<mysql_errno<&my_connection>> { fprintf<stderr,"retrieveinqueryerror:%s\n",mysql_error<&my_connection>>; } if<strlen<buf>>0> { strcat<buf,"#">; printf<"%s\n",buf>; if<send<client_fd,buf,strlen<buf>,0>==-1> { fprintf<stderr,"sendinqueryfailed%s\n",strerror<errno>>; } } else { printf<"nothing\n">; if<send<client_fd,",",strlen<",">,0>==-1> { fprintf<stderr,"sendinqueryfailed%s\n",strerror<errno>>; } } mysql_free_result<res_ptr>; } } else { fprintf<stderr,"query%d:%s\n",mysql_errno<&my_connection>,mysql_error<&my_connection>>; } close<client_fd>; returnNULL;}1.2自动更XX票#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<errno.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<fcntl.h>#include<sys/epoll.h>#include<netdb.h>#include<pthread.h>#include<stdarg.h>#include"btbs.h"#defineMAXEVENTS64#defineQUERY_PRE_SALE2//查询预售期#defineQUERY_TICKETS3//查询车票#defineBOOK_TICKETS4//订票#defineQUERY_ORDERS_TODAY5//查询今日订单#defineQUERY_ORDERS6//查询订单#definePUSH_MESSAGE7//推送消息#defineCHECK_ACCOUNT9//验证账户#defineQUERY_PERSON_INFO10//查询个人信息#defineMODIFY_PASSWD11//修改密码#defineQUERY_SCHOOL_BUS12//查询校车信息#defineDROP_TICKETS13//退票intstr_split<char*str1,...>;intget_first_field<constchar*str>;intmain<intarg,char*args[]>{ if<arg<2> { return-1; } intport=atoi<args[1]>; intst=socket<AF_INET,SOCK_STREAM,0>;//初始化socket structsockaddr_inaddr;//定义一个ip地址结构 memset<&addr,0,sizeof<addr>>; addr.sin_family=AF_INET;//将addr结构的属性定位位TCP/IP地址 addr.sin_port=htons<port>;//将本地字节顺序转化位网论字节顺序 addr.sin_addr.s_addr=htonl<INADDR_ANY>;//INADDR_ANY代表这个server上所有的地址 //将IP与server程序绑定 if<bind<st,<structsockaddr*>&addr,sizeof<addr>>==-1> { printf<"bindfailed%s\n",strerror<errno>>; returnEXIT_FAILURE; } //设置socket为非阻塞的 intflags,ret; flags=fcntl<st,F_GETFL,0>; if<flags==-1> { printf<"fcntl%s\n",strerror<errno>>; returnEXIT_FAILURE; } flags|=O_NONBLOCK; ret=fcntl<st,F_SETFL,flags>; if<ret==-1> { printf<"fcntl%s\n",strerror<errno>>; returnEXIT_FAILURE; } //监听客户端的连接请求 ret=listen<st,SOMAXCONN>; if<ret==-1> { printf<"listen%s\n",strerror<errno>>; returnEXIT_FAILURE; } //连接数据库 MYSQLmy_connection; mysql_init<&my_connection>; if<mysql_real_connect<&my_connection,"localhost","root","2222","ReservationSystem",0,NULL,0>> { mysql_query<&my_connection,"setnames'utf8'">; printf<"connectionsuccess\n">; } else { fprintf<stderr,"connectionfailed\n">; if<mysql_errno<&my_connection>> { fprintf<stderr,"connectionerror%d:%s\n",mysql_errno<&my_connection>,mysql_error<&my_connection>>; } returnEXIT_FAILURE; } //创建一个epoll对象 intefd=epoll_create1<0>; if<efd==-1> { printf<"epoll_create%s\n",strerror<errno>>; returnEXIT_FAILURE; } //往epoll对象添加时间 structepoll_eventevent; structepoll_event*events; event.data.fd=st; event.events=EPOLLIN|EPOLLET;//读入,边缘触发方式 ret=epoll_ctl<efd,EPOLL_CTL_ADD,st,&event>; if<ret==-1> { printf<"epoll_ctl%s\n",strerror<errno>>; returnEXIT_FAILURE; } //bufferwhereeventsarereturned events=calloc<MAXEVENTS,sizeof<event>>; //theeventloop while<1> { intn,i; n=epoll_wait<efd,events,MAXEVENTS,-1>;//没有事件发生时一直阻塞 for<i=0;i<n;i++> { if<<events[i].events&EPOLLERR>||\ <events[i].events&EPOLLHUP>||\ <!<events[i].events&EPOLLIN>>> { //anerrorhasoccuredonthisfd,orthesocketisreadyfor //reading printf<"epollerror%s\n",strerror<errno>>; close<events[i].data.fd>; continue; } elseif<st==events[i].data.fd> { //wehaveanotificationonthelisteningsocket, //whichmeansoneormoreincomingconnections while<1> { structsockaddrin_addr; socklen_tin_len; intinfd; charhbuf[NI_MAXHOST],sbuf[NI_MAXSERV]; in_len=sizeof<in_addr>; infd=accept<st,&in_addr,&in_len>; if<infd==-1> { if<<errno==EAGAIN>||<errno==EWOULDBLOCK>> { //wehaveprocessedallincomingconnections break; } else { printf<"accept%s\n",strerror<errno>>; break; } } ret=getnameinfo<&in_addr,in_len,hbuf,sizeof<hbuf>,sbuf,sizeof<sbuf>,NI_NUMERICHOST|NI_NUMERICHOST>;//flag参数,以数字名返回主机地址和服务地 if<ret==0> {printf<"acceptedconnectionondescriptor%d<host=%s,port=%s>\n",infd,hbuf,sbuf>; } //maketheincomingsocketnon-blockingandaddittothelistoffdstomonitor flags=fcntl<infd,F_GETFL,0>; if<flags==-1> { printf<"fcntl%s\n",strerror<errno>>; returnEXIT_FAILURE; } flags|=O_NONBLOCK; ret=fcntl<infd,F_SETFL,flags>; if<ret==-1> { printf<"fcntl%s\n",strerror<errno>>; returnEXIT_FAILURE; } event.data.fd=infd; event.events=EPOLLIN|EPOLLET; ret=epoll_ctl<efd,EPOLL_CTL_ADD,infd,&event>; if<ret==-1> { printf<"epoll_ctl%s\n",strerror<errno>>; returnEXIT_FAILURE; } } continue; } else { //wehavedataonthefdwaitingtoberead.readanddisplayit. //wemustreadwhateverdataisavailablecompletely,asweare //runninginedge-triggeredmodeandwon'tgetanotificationagain //forthesamedata intdone=0; while<1> { ssize_tcount; charbuf[512]; memset<buf,0,sizeof<buf>>; count=read<events[i].data.fd,buf,sizeof<buf>>; if<count==-1> { //iferrno==EAGAIN,thatmeanswehavereadalldata. //sogobacktothemainloop if<errno!=EAGAIN> { printf<"read%s\n",strerror<errno>>; done=1; } break; } elseif<count==0> { //endoffile.theremotehasclosedtheconnection done=1; break; } //splitthestringbuftofetchfieldinfomation //forexample,ifbufisstring"10,studentId",thefieldincludes10andstudentId charcmd[1024]; memset<cmd,0,sizeof<cmd>>; intfunc_id=get_first_field<buf>; arg_attrarg; arg.my_connection=&my_connection; arg.client_fd=events[i].data.fd; pthread_tthr; switch<func_id> { caseQUERY_PRE_SALE: { send<events[i].data.fd,"3",sizeof<"3">,0>; break; } caseCHECK_ACCOUNT: { charfid[3]; memset<fid,0,sizeof<fid>>; charstudentId[20]; memset<studentId,0,sizeof<studentId>>; charpasswd[20]; memset<passwd,0,sizeof<passwd>>; intretval=str_split<buf,fid,studentId,passwd>; sprintf<cmd,"select*fromAccountwhereaccountno='%s'andaccountkey='%s'",studentId,passwd>; arg.cmd=cmd; pthread_create<&thr,NULL,check_account,&arg>; break; } caseMODIFY_PASSWD: { charfid[3]; memset<fid,0,sizeof<fid>>; charstudentId[20]; memset<studentId,0,sizeof<studentId>>; charpasswd[20]; memset<passwd,0,sizeof<passwd>>; charnew_passwd[20]; memset<passwd,0,sizeof<passwd>>; intretval=str_split<buf,fid,studentId,passwd,new_passwd>; sprintf<cmd,"updateAccountsetaccountkey='%s'whereaccountno='%s'andaccountkey='%s'",new_passwd,studentId,passwd>; arg.cmd=cmd; pthread_create<&thr,NULL,modify_passwd,&arg>; break; } caseQUERY_PERSON_INFO: { charfid[3]; memset<fid,0,sizeof<fid>>; charstudentId[20]; memset<studentId,0,sizeof<studentId>>; intretval=str_split<buf,fid,studentId>; sprintf<cmd,"select*fromStudentwherestuno='%s'",studentId>; arg.cmd=cmd; pthread_create<&thr,NULL,query,&arg>; break; } caseQUERY_TICKETS: { charfid[3]={0}; charstartpos[50]={0}; charyear[6]={0}; charmonth[3]={0}; charday[4]={0}; intretval=str_split<buf,fid,startpos,year,month,day>; sprintf<cmd,"selectticketsnofromTicketsLeftwherebusnoin<selectbusnofromSchoolBuswherestartplace='%s'>andbusdate='%s-%s-%s'",startpos,year,month,day>; arg.cmd=cmd; pthread_create<&thr,NULL,query,&arg>; break; } caseQUERY_ORDERS: { charfid[3]={0}; charstudentId[20]={0}; intretval=str_split<buf,fid,studentId>; sprintf<cmd,"selectSchoolBus.startplace,stuno,busdate,bustimefromTicketsReservation,SchoolBuswhereTicketsReservation.busno=SchoolBus.busnoandstuno='%s'orderbybusdateDESC",studentId>; arg.cmd=cmd; pthread_create<&thr,NULL,query,&arg>; break; } caseBOOK_TICKETS: { charfid[3]={0}; charstudentId[20]={0}; charstartplace[50]={0}; charyear[6]={0}; charmonth[3]={0}; charday[4]={0}; charweekend[3]={0}; intretval=str_split<buf,fid,studentId,startplace,year,month,day,weekend>; arg.op_cmd[0]=studentId; arg.op_cmd[1]=startplace; arg.op_cmd[2]=year; arg.op_cmd[3]=month; arg.op_cmd[4]=day; arg.op_cmd[5]=weekend; sprintf<cmd,"select1fromTicketsReservationwherebusno=<selectbusnofromSchoolBuswherestartplace='%s'andweekend='%s'>andstuno='%s'andbusdate='%s-%s-%s'limit1",startplace,weekend,studentId,year,month,day>; arg.cmd=cmd; pthread_create<&thr,NULL,book_ticket,&arg>; break; } caseQUERY_ORDERS_TODAY: { charfid[3]={0}; charstudentId[20]={0}; charyear[6]={0}; charmonth[3]={0}; charday[4]={0}; intretval=str_split<buf,fid,studentId,year,month,day>; // sprintf<cmd,"select*fromTicketsReservationwherestuno='%s'andbusdate='%s-%s-%s'",studentId,year,month,day>; sprintf<cmd,"selectSchoolBus.startplace,stuno,busdate,bustimefromTicketsReservation,SchoolBuswhereTicketsReservation.busno=SchoolBus.busnoandstuno='%s'andbusdate='%s-%s-%s'",studentId,year,month,day>; arg.cmd=cmd; pthread_create<&thr,NULL,query,&arg>; break; } caseQUERY_SCHOOL_BUS: { charfid[3]={0}; intretval=str_split<buf,fid>; sprintf<cmd,"select*fromSchoolBus">; arg.cmd=cmd; pthread_create<&thr,NULL,query,&arg>; break; } caseDROP_TICKETS: { charfid[3]={0}; charstudentId[20]={0}; charstartplace[50]={0}; charyear[6]={0}; charmonth[3]={0}; charday[4]={0}; charweekend[3]={0}; intretval=str_split<buf,fid,studentId,startplace,year,month,day,weekend>; arg.op_cmd[0]=studentId; arg.op_cmd[1]=startplace; arg.op_cmd[2]=year; arg.op_cmd[3]=month; arg.op_cmd[4]=day; arg.op_cmd[5]=weekend; sprintf<cmd,"deletefromTicketsReservationwherebusno=<selectbusnofromSchoolBuswherestartplace='%s'andweekend='%s'>andstuno='%s'andbusdate='%s-%s-%s'",startplace,weekend,studentId,year,month,day>; arg.cmd=cmd; pthread_create<&thr,NULL,drop_ticket,&arg>; break; } } } if<done> { printf<"closedconnectionondescriptor%d\n",events[i].data.fd>; //closingthedescriptorwillmakeepollremoveitfromtheset //ofdescriptorswhicharemonitored //close<events[i].data.fd>; } } } } free<events>; close<st>; returnEXIT_SUCCESS;}staticintstr_split<char*str1,...>{ intnum=0; va_listap; constchardelim[]={","}; char*t=NULL; char*p=NULL; va_start<ap,str1>; t=strtok<str1,delim>; while<t!=NULL&&<p=va_arg<ap,char*>>!=NULL> { num++; strcpy<p,t>; t=strtok<NULL,delim>; } va_end<ap>; returnnum;}staticintget_first_field<constchar*str>{ char*p=strchr<str,','>; charid[3]; memset<id,0,sizeof<id>>; strncpy<id,str,p-str>; intretval=atoi<id>; returnretval;}1.3响应客户端实现#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<errno.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<fcntl.h>#include<sys/epoll.h>#include<netdb.h>#include<pthread.h>#include<stdarg.h>#include"btbs.h"#defineMAXEVENTS64#defineQUERY_PRE_SALE2//查询预售期#defineQUERY_TICKETS3//查询车票#defineBOOK_TICKETS4//订票#defineQUERY_ORDERS_TODAY5//查询今日订单#defineQUERY_ORDERS6//查询订单#definePUSH_MESSAGE7//推送消息#defineCHECK_ACCOUNT9//验证账户#defineQUERY_PERSON_INFO10//查询个人信息#defineMODIFY_PASSWD11//修改密码#defineQUERY_SCHOOL_BUS12//查询校车信息#defineDROP_TICKETS13//退票intstr_split<char*str1,...>;intget_first_field<constchar*str>;intmain<intarg,char*args[]>{ if<arg<2> { return-1; } intport=atoi<args[1]>; intst=socket<AF_INET,SOCK_STREAM,0>;//初始化socket structsockaddr_inaddr;//定义一个ip地址结构 memset<&addr,0,sizeof<addr>>; addr.sin_family=AF_INET;//将addr结构的属性定位位TCP/IP地址 addr.sin_port=htons<port>;//将本地字节顺序转化位网论字节顺序 addr.sin_addr.s_addr=htonl<INADDR_ANY>;//INADDR_ANY代表这个server上所有的地址 //将IP与server程序绑定 if<bind<st,<structsockaddr*>&addr,sizeof<addr>>==-1> { printf<"bindfailed%s\n",strerror<errno>>; returnEXIT_FAILURE; } //设置socket为非阻塞的 intflags,ret; flags=fcntl<st,F_GETFL,0>; if<flags==-1> { printf<"fcntl%s\n",strerror<errno>>; returnEXIT_FAILURE; } flags|=O_NONBLOCK; ret=fcntl<st,F_SETFL,flags>; if<ret==-1> { printf<"fcntl%s\n",strerror<errno>>; returnEXIT_FAILURE; } //监听客户端的连接请求 ret=listen<st,SOMAXCONN>; if<ret==-1> { printf<"listen%s\n",strerror<errno>>; returnEXIT_FAILURE; } //连接数据库 MYSQLmy_connection; mysql_init<&my_connection>; if<mysql_real_connect<&my_connection,"localhost","root","2222","ReservationSystem",0,NULL,0>> { mysql_query<&my_connection,"setnames'utf8'">; printf<"connectionsuccess\n">; } else { fprintf<stderr,"connectionfailed\n">; if<mysql_errno<&my_connection>> { fprintf<stderr,"connectionerror%d:%s\n",mysql_errno<&my_connection>,mysql_error<&my_connection>>; } returnEXIT_FAILURE; } //创建一个epoll对象 intefd=epoll_create1<0>; if<efd==-1> { printf<"epoll_create%s\n",strerror<errno>>; returnEXIT_FAILURE; } //往epoll对象添加时间 structepoll_eventevent; structepoll_event*events; event.data.fd=st; event.events=EPOLLIN|EPOLLET;//读入,边缘触发方式 ret=epoll_ctl<efd,EPOLL_CTL_ADD,st,&event>; if<ret==-1> { printf<"epoll_ctl%s\n",strerror<errno>>; returnEXIT_FAILURE; } //bufferwhereeventsarereturned events=calloc<MAXEVENTS,sizeof<event

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论