版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
..《移動(dòng)通信與無(wú)線網(wǎng)絡(luò)》大作業(yè)報(bào)告校車(chē)訂票系統(tǒng)課程:學(xué)校:組長(zhǎng):組員:完成時(shí)間:目錄TOC\z\o"1-3"\u\h一需求分析⑺編制設(shè)計(jì)說(shuō)明書(shū)??傮w設(shè)計(jì)過(guò)程可分為兩個(gè)主要階段:<1>功能設(shè)計(jì),確定車(chē)站售票系統(tǒng)的實(shí)現(xiàn)方案;結(jié)構(gòu)設(shè)計(jì),確定該軟件的結(jié)構(gòu)。功能設(shè)計(jì)是在需求分析的基礎(chǔ)上進(jìn)行的,這里所說(shuō)的"功能"是泛指的,不僅指問(wèn)題定義中列出的功能,還包括軟件定義時(shí)確定的任何一個(gè)獨(dú)立的數(shù)據(jù)加工或處理步驟,例如添加、刪除、查詢和各個(gè)特定功能的算法實(shí)現(xiàn)等。<2>結(jié)構(gòu)設(shè)計(jì),是將整個(gè)系統(tǒng)按照不同的功能和層次劃分為一個(gè)個(gè)功能簡(jiǎn)單明確且相對(duì)獨(dú)立的部分〔模塊,每個(gè)模塊實(shí)現(xiàn)系統(tǒng)的一項(xiàng)具體功能,自頂向下,逐步細(xì)化。結(jié)構(gòu)設(shè)計(jì)是確定程序由哪些模塊組成,以及這些模塊之間的關(guān)系。1.1系統(tǒng)功能設(shè)計(jì)本系統(tǒng)分三個(gè)模塊,登錄功能模塊;管理員功能模塊,實(shí)現(xiàn)車(chē)票和車(chē)次管理;普通用戶功能模塊,實(shí)現(xiàn)車(chē)票和個(gè)人信息管理。校車(chē)車(chē)票網(wǎng)上訂票系統(tǒng)簡(jiǎn)單、操作靈活、方便、反應(yīng)快速、計(jì)算準(zhǔn)確,系統(tǒng)運(yùn)行穩(wěn)定、安全可靠,而且有良好的交互界面,讓使用者可以方便、快速地掌握。1.2系統(tǒng)的總體結(jié)構(gòu)根據(jù)系統(tǒng)分析,按照結(jié)構(gòu)化程序設(shè)計(jì)的要求得到了下面的系統(tǒng)功能模塊圖:刪除車(chē)次發(fā)布車(chē)次刪除車(chē)次發(fā)布車(chē)次更新車(chē)次管理員功能選擇更新車(chē)次管理員功能選擇校車(chē)消息推送消息校車(chē)消息推送消息天氣信息天氣信息校車(chē)票網(wǎng)上訂票系統(tǒng)校車(chē)票網(wǎng)上訂票系統(tǒng)修改信息修改信息修改信息修改信息賬戶重置賬戶重置普通用戶功能選擇普通用戶功能選擇查詢信息車(chē)次查詢查詢信息車(chē)次查詢時(shí)間查詢時(shí)間查詢車(chē)票管理車(chē)票管理預(yù)訂車(chē)票退去車(chē)票退去車(chē)票圖5校車(chē)車(chē)票網(wǎng)上訂票系統(tǒng)總體功能圖1.3子模塊描述各個(gè)子模塊描述如下:1.登錄功能模塊:打開(kāi)手機(jī)應(yīng)用程序,進(jìn)入登錄功能模塊,選擇登錄身份區(qū)別是普通用戶或是系統(tǒng)管理員。2.管理員功能模塊:車(chē)次管理功能模塊主要實(shí)現(xiàn)車(chē)次的添加、車(chē)次更新、刪除等功能。同時(shí)為了更好的提供出行信息,管理員可以根據(jù)天氣信息推薦學(xué)生注意天氣的變化等信息,溫馨地關(guān)心學(xué)生。3.普通用戶功能模塊:<1>查詢功能模塊:主要完成車(chē)票信息查詢、訂票信息查詢等功能。<2>車(chē)票管理功能模塊:主要完成校車(chē)車(chē)票的訂票,退票等功能。<3>個(gè)人信息管理功能模塊:主要完成個(gè)人信息的修改等功能。四視圖設(shè)計(jì)1E-R圖2數(shù)據(jù)流圖數(shù)據(jù)流程圖是以圖形的方式表達(dá)在問(wèn)題中信息的變換和傳遞過(guò)程。它把系統(tǒng)看成是由數(shù)據(jù)流聯(lián)系的各種概念的組合,用分解及抽象手段來(lái)控制需求分析的復(fù)雜性,采用分層的數(shù)據(jù)流程圖來(lái)表示一個(gè)復(fù)雜的系統(tǒng)。校車(chē)車(chē)票網(wǎng)上訂票系統(tǒng)系統(tǒng)登錄數(shù)據(jù)流圖:開(kāi)始開(kāi)始登錄登錄身份識(shí)別身份識(shí)別管理員/普通用戶管理員操作用戶管理員操作用戶結(jié)束結(jié)束圖6校車(chē)車(chē)票網(wǎng)上訂票系統(tǒng)登錄管理數(shù)據(jù)流圖校車(chē)車(chē)票網(wǎng)上訂票系統(tǒng)車(chē)票查詢數(shù)據(jù)流圖:普通用戶普通用戶登錄登錄查詢選擇查詢選擇車(chē)次信息查詢訂票信息查詢個(gè)人信息查詢修改個(gè)人信息車(chē)次信息查詢訂票信息查詢個(gè)人信息查詢修改個(gè)人信息結(jié)束結(jié)束圖7校車(chē)車(chē)票網(wǎng)上訂票系統(tǒng)查詢管理數(shù)據(jù)流圖校車(chē)車(chē)票網(wǎng)上訂票系統(tǒng)車(chē)次、車(chē)票、時(shí)間管理數(shù)據(jù)流圖:圖9校車(chē)車(chē)票網(wǎng)上訂票系統(tǒng)車(chē)次、車(chē)票管理數(shù)據(jù)流圖3程序描述3.1客戶端程序本套校車(chē)車(chē)票訂票系統(tǒng)軟件的客戶端應(yīng)用程序以手機(jī)軟件程序編寫(xiě),客戶使用手機(jī)安裝下載通過(guò)互連網(wǎng)絡(luò)對(duì)數(shù)據(jù)庫(kù)進(jìn)行訪問(wèn),并完成客戶端可以完成的功能。3.2服務(wù)器端程序本套校車(chē)車(chē)票訂票系統(tǒng)軟件的服務(wù)器端應(yīng)用程序,在linux平臺(tái)下編寫(xiě)前臺(tái)控制軟件,用電腦主機(jī)充當(dāng)服務(wù)器,管理員通過(guò)使用該軟件來(lái)進(jìn)行對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行管理。3.3后臺(tái)數(shù)據(jù)庫(kù)本套校車(chē)車(chē)票訂票系統(tǒng)軟件的后臺(tái)數(shù)據(jù)庫(kù)使用MySQL來(lái)搭建后臺(tái)數(shù)據(jù)庫(kù)服務(wù)器,用來(lái)存放所有的數(shù)據(jù)。4功能描述4.1整體流程設(shè)計(jì)校車(chē)訂票系統(tǒng)管理員登陸用戶登錄用戶注冊(cè)前臺(tái)瀏覽身份認(rèn)證身份認(rèn)證認(rèn)證失敗認(rèn)證失敗認(rèn)證成功認(rèn)證成功后臺(tái)管理模塊用戶前臺(tái)模塊圖10整體系統(tǒng)設(shè)計(jì)思路4.2客戶端的主要功能3.2.1用戶訂票的全部過(guò)程用戶登陸成功用戶登陸成功查詢車(chē)次查詢余票
預(yù)定車(chē)票
注銷(xiāo)退訂車(chē)票用戶中心圖11用戶訂票流程圖圖12訂票邏輯圖圖13歷史訂單查詢及刪除邏輯4.3服務(wù)器的主要功能管理員登陸成功管理員登陸成功用戶管理校車(chē)管理訂票管理帳號(hào)管理日志管理管理員信息用戶信息校車(chē)安排表余票信息消息推送訂票信息退票信息學(xué)生數(shù)據(jù)庫(kù)系統(tǒng)日志注銷(xiāo)圖14管理員程序?qū)崿F(xiàn)流程4.4軟件時(shí)序圖設(shè)計(jì)軟件程序時(shí),時(shí)序圖包含如下的四個(gè)元素:1>對(duì)象,2>生命線,3>消息,4>激活。圖14用戶預(yù)訂車(chē)票時(shí)序圖圖15用戶退票時(shí)序圖4.5數(shù)據(jù)庫(kù)接口本套校車(chē)訂票系統(tǒng)軟件服務(wù)器端的程序是使用eclipse來(lái)編寫(xiě)完成,建立eclipse與數(shù)據(jù)庫(kù)的連接使用了ADODB的對(duì)象來(lái)完成,每個(gè)模塊中都使用了Recordset、Command、Connection的對(duì)象,因此在模塊中對(duì)三者的對(duì)象進(jìn)行定義<分別為:rs、cmd、cn>,并且將cn連接數(shù)據(jù)庫(kù)的語(yǔ)句寫(xiě)好并打開(kāi)連接,在其他的模塊中共同調(diào)用這三個(gè)對(duì)象來(lái)對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作。圖16軟件具體實(shí)現(xiàn)接口五程序?qū)崿F(xiàn)1.1客戶端通信方式有和Socket兩種。<1>通信:連接使用的是"請(qǐng)求—響應(yīng)方式",即在請(qǐng)求時(shí)建立連接通道,當(dāng)客戶端向服務(wù)器發(fā)送請(qǐng)求后,服務(wù)器端才能向客戶端返回?cái)?shù)據(jù)<2>Socket通信:在雙方建立起連接后就可以直接進(jìn)行數(shù)據(jù)的傳輸,在連接時(shí)可實(shí)現(xiàn)信息的主動(dòng)推送,而不需要每次由客戶端想服務(wù)器發(fā)送請(qǐng)求圖17TCP通信模型的Socket于是本設(shè)計(jì)選擇安卓Socket編程方式實(shí)現(xiàn):服務(wù)器端:首先聲明一個(gè)ServerSocket對(duì)象并且指定端口號(hào),然后調(diào)用Serversocket的accept<>方法接收客戶端的數(shù)據(jù),accept<>方法在沒(méi)有數(shù)據(jù)進(jìn)行接收的處于堵塞狀態(tài)。一旦接收到數(shù)據(jù),通過(guò)inputstream讀取接收的數(shù)據(jù)客戶端:創(chuàng)建一個(gè)Socket對(duì)象,指定服務(wù)器端的ip地址和端口通過(guò)inputstream讀取數(shù)據(jù),獲取服務(wù)器發(fā)出的數(shù)據(jù)最后將要發(fā)送的數(shù)據(jù)寫(xiě)入到outputstream即可進(jìn)行TCP協(xié)議的socket數(shù)據(jù)傳輸。天氣預(yù)報(bào)的實(shí)現(xiàn)部分,通過(guò)資料查詢,我們發(fā)現(xiàn)有如下免費(fèi)天氣預(yù)報(bào)獲取途徑,如下所示:Google的天氣預(yù)報(bào)API中央氣象臺(tái)中國(guó)氣象局WeatherWebService其中WebXml
天氣預(yù)報(bào)Web服務(wù),數(shù)據(jù)每2.5小時(shí)左右自動(dòng)更新一次,準(zhǔn)確可靠。包括340多個(gè)中國(guó)主要城市和60多個(gè)國(guó)外主要城市三日內(nèi)的天氣預(yù)報(bào)數(shù)據(jù)。于是我們選擇這一資源進(jìn)行天氣信息的推送。1.2服務(wù)器在服務(wù)器上的程序由于要接受多個(gè)用戶的請(qǐng)求,程序的靈活性和健壯性必須要得到保證,于是本設(shè)計(jì)采用多線程程序設(shè)計(jì)思想,對(duì)校車(chē)系統(tǒng)進(jìn)行了一些測(cè)試。多線程程序有如下優(yōu)點(diǎn):1>線程間方便的通信機(jī)制2>提高應(yīng)用程序響應(yīng)3>使多CPU系統(tǒng)更加有效4>改善程序結(jié)構(gòu)設(shè)計(jì)思路:多線程的程序結(jié)構(gòu)能夠極大的便利程序設(shè)計(jì),本設(shè)計(jì)將整個(gè)系統(tǒng)進(jìn)行功能模塊的分解,使得每個(gè)功能模塊獨(dú)立不相關(guān),每個(gè)模塊占用一個(gè)線程,獨(dú)立和協(xié)調(diào)地完成整個(gè)系統(tǒng)的功能,這種程序設(shè)計(jì)思路方便管理和增加新的功能,可擴(kuò)展性強(qiáng)。多線程列表服務(wù)器是否可達(dá)預(yù)售期查詢余票查詢預(yù)定車(chē)票今日訂單查詢訂單查詢消息詳細(xì)信息賬號(hào)驗(yàn)證個(gè)人信息查詢密碼修改班車(chē)信息查詢退票圖18多線程劃分列表事件監(jiān)聽(tīng)方面,epoll
是Linux內(nèi)核中的一種可擴(kuò)展IO事件處理機(jī)制,最早在Linux2.5.44內(nèi)核中引入,可被用于代替POSIXselect和poll系統(tǒng)調(diào)用,并且在具有大量應(yīng)用程序請(qǐng)求時(shí)能夠獲得較好的性能,epoll與FreeBSD的kqueue類(lèi)似,都向用戶空間提供了自己的文件描述符來(lái)進(jìn)行操作。epoll負(fù)責(zé)監(jiān)聽(tīng)來(lái)自應(yīng)用程序的TCP/IP請(qǐng)求,并反饋信息到手機(jī)應(yīng)用端1.3加密與解密在與服務(wù)器之間的數(shù)據(jù)交互中,除了可以使用post請(qǐng)求來(lái)進(jìn)行加密請(qǐng)求之外,我們可以使用常見(jiàn)的加密算法,對(duì)數(shù)據(jù)進(jìn)行加密。本設(shè)計(jì)采用DES加密算法。DES<DataEncryptionStandard>,即數(shù)據(jù)加密標(biāo)準(zhǔn),是一種使用密鑰加密的塊算法,DES算法的入口參數(shù)有三個(gè):Key、Data、Mode。其中Key為7個(gè)字節(jié)的工作密鑰;Data是要被加密或被解密的8個(gè)字節(jié)數(shù)據(jù);Mode為DES的工作方式,分為:加密或解密。DES是一種對(duì)稱的加密算法,加密和解密使用同一個(gè)密鑰。本設(shè)計(jì)使用DES算法進(jìn)行加密,采用的是CBC模式,填充方式采用PKCS5Padding。
CBC模式指的是加密塊鏈模式,算法加入了初始向量。下面的代碼就是獲取一個(gè)初始向量,這種模式的特點(diǎn)是:
1>加密的密文長(zhǎng)度為8個(gè)字節(jié);2>當(dāng)明文使用相同的密鑰和初始向量的時(shí)候,CBC模式總是產(chǎn)生相同的密文;3>密文塊不能再次排列;4>為避免相同的明文產(chǎn)生相同的密文,可以使用不同的初始化向量;5>一個(gè)錯(cuò)誤發(fā)生以后,當(dāng)前和以后的密文都會(huì)被影響。
在不同的平臺(tái)上,只要能保證這幾個(gè)參數(shù)的一致,就可以實(shí)現(xiàn)加密和解密的一致性:加密和解密的密鑰一致;采用CBC模式的時(shí)候,要保證初始向量一致;采用相同的填充模式。六總結(jié)在現(xiàn)今移動(dòng)互聯(lián)網(wǎng)浪潮下,校車(chē)訂票系統(tǒng)作為一個(gè)典型的應(yīng)用,正在便利我們的生活,人們的生活越來(lái)越離不開(kāi)手機(jī),人們的大部分活動(dòng),交友,娛樂(lè)也越來(lái)越多依賴手機(jī)。關(guān)于手機(jī)APP的設(shè)計(jì)和用戶需求分析,也給我們小組所有成員帶來(lái)了許多思考。小組設(shè)計(jì)的初衷在于解決生活中的一些力所能及的事情,或許這些設(shè)計(jì)不算很完美,卻鍛煉了我們發(fā)現(xiàn)問(wèn)題,解決問(wèn)題,提出問(wèn)題的能力,讓我們?cè)谖磥?lái)的科研路上,可以腳踏實(shí)地,少走彎路。本設(shè)計(jì)將校車(chē)訂票系統(tǒng)分三部分進(jìn)行,手機(jī)客戶端,服務(wù)器端,數(shù)據(jù)庫(kù)。手機(jī)客戶端界面設(shè)計(jì)美觀,操作簡(jiǎn)單方便;服務(wù)器端在筆記本電腦上,運(yùn)行在Linux操作系統(tǒng)下,采用多線程框架編寫(xiě)程序,方便程序管理與更新。校車(chē)訂票系統(tǒng)從功能上實(shí)現(xiàn):服務(wù)端目前具備發(fā)布以及更新訂票信息,注冊(cè)帳號(hào),管理數(shù)據(jù)庫(kù)等功能;客戶端上具備訂票信息查詢,余票查詢,注冊(cè)帳號(hào),天氣信息獲取,預(yù)訂車(chē)票以及退訂車(chē)票等功能。 不過(guò)本設(shè)計(jì)還存在許多不足的地方,表現(xiàn)在如下二個(gè)方面:1>進(jìn)度上:由于沒(méi)有獲取國(guó)科大學(xué)生的基本信息以及校車(chē)的真實(shí)信息,校車(chē)訂票系統(tǒng)還未整體測(cè)試和完善。此外穩(wěn)定性及流暢性各種方面都未獲得驗(yàn)證。2>設(shè)計(jì)上:校車(chē)訂票系統(tǒng)設(shè)計(jì)思路傳統(tǒng),創(chuàng)新上存在不足。附錄服務(wù)器程序1.1數(shù)據(jù)庫(kù)功能實(shí)現(xiàn)#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,"雁棲湖校區(qū)">==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,"雁棲湖校區(qū)">==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,"玉泉路校區(qū)">==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自動(dòng)更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//查詢預(yù)售期#defineQUERY_TICKETS3//查詢車(chē)票#defineBOOK_TICKETS4//訂票#defineQUERY_ORDERS_TODAY5//查詢今日訂單#defineQUERY_ORDERS6//查詢訂單#definePUSH_MESSAGE7//推送消息#defineCHECK_ACCOUNT9//驗(yàn)證賬戶#defineQUERY_PERSON_INFO10//查詢個(gè)人信息#defineMODIFY_PASSWD11//修改密碼#defineQUERY_SCHOOL_BUS12//查詢校車(chē)信息#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;//定義一個(gè)ip地址結(jié)構(gòu) memset<&addr,0,sizeof<addr>>; addr.sin_family=AF_INET;//將addr結(jié)構(gòu)的屬性定位位TCP/IP地址 addr.sin_port=htons<port>;//將本地字節(jié)順序轉(zhuǎn)化位網(wǎng)論字節(jié)順序 addr.sin_addr.s_addr=htonl<INADDR_ANY>;//INADDR_ANY代表這個(gè)server上所有的地址 //將IP與server程序綁定 if<bind<st,<structsockaddr*>&addr,sizeof<addr>>==-1> { printf<"bindfailed%s\n",strerror<errno>>; returnEXIT_FAILURE; } //設(shè)置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; } //監(jiān)聽(tīng)客戶端的連接請(qǐng)求 ret=listen<st,SOMAXCONN>; if<ret==-1> { printf<"listen%s\n",strerror<errno>>; returnEXIT_FAILURE; } //連接數(shù)據(jù)庫(kù) 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; } //創(chuàng)建一個(gè)epoll對(duì)象 intefd=epoll_create1<0>; if<efd==-1> { printf<"epoll_create%s\n",strerror<errno>>; returnEXIT_FAILURE; } //往epoll對(duì)象添加時(shí)間 structepoll_eventevent; structepoll_event*events; event.data.fd=st; event.events=EPOLLIN|EPOLLET;//讀入,邊緣觸發(fā)方式 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>;//沒(méi)有事件發(fā)生時(shí)一直阻塞 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參數(shù),以數(shù)字名返回主機(jī)地址和服務(wù)地 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響應(yīng)客戶端實(shí)現(xiàn)#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//查詢預(yù)售期#defineQUERY_TICKETS3//查詢車(chē)票#defineBOOK_TICKETS4//訂票#defineQUERY_ORDERS_TODAY5//查詢今日訂單#defineQUERY_ORDERS6//查詢訂單#definePUSH_MESSAGE7//推送消息#defineCHECK_ACCOUNT9//驗(yàn)證賬戶#defineQUERY_PERSON_INFO10//查詢個(gè)人信息#defineMODIFY_PASSWD11//修改密碼#defineQUERY_SCHOOL_BUS12//查詢校車(chē)信息#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;//定義一個(gè)ip地址結(jié)構(gòu) memset<&addr,0,sizeof<addr>>; addr.sin_family=AF_INET;//將addr結(jié)構(gòu)的屬性定位位TCP/IP地址 addr.sin_port=htons<port>;//將本地字節(jié)順序轉(zhuǎn)化位網(wǎng)論字節(jié)順序 addr.sin_addr.s_addr=htonl<INADDR_ANY>;//INADDR_ANY代表這個(gè)server上所有的地址 //將IP與server程序綁定 if<bind<st,<structsockaddr*>&addr,sizeof<addr>>==-1> { printf<"bindfailed%s\n",strerror<errno>>; returnEXIT_FAILURE; } //設(shè)置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; } //監(jiān)聽(tīng)客戶端的連接請(qǐng)求 ret=listen<st,SOMAXCONN>; if<ret==-1> { printf<"listen%s\n",strerror<errno>>; returnEXIT_FAILURE; } //連接數(shù)據(jù)庫(kù) 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; } //創(chuàng)建一個(gè)epoll對(duì)象 intefd=epoll_create1<0>; if<efd==-1> { printf<"epoll_create%s\n",strerror<errno>>; returnEXIT_FAILURE; } //往epoll對(duì)象添加時(shí)間 structepoll_eventevent; structepoll_event*events; event.data.fd=st; event.events=EPOLLIN|EPOLLET;//讀入,邊緣觸發(fā)方式 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. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- KPC智能家居課程設(shè)計(jì)
- uml與數(shù)據(jù)庫(kù)課程設(shè)計(jì)
- 幼兒認(rèn)知?jiǎng)游镎n程設(shè)計(jì)
- 打飛機(jī)c 課程設(shè)計(jì)
- 小班種玉米課程設(shè)計(jì)
- 微型木屋課程設(shè)計(jì)
- 小麥清理工藝課程設(shè)計(jì)
- 幼兒園蹦爆米花課程設(shè)計(jì)
- 幼兒園瑜伽教學(xué)課程設(shè)計(jì)
- 房地產(chǎn)項(xiàng)目的課程設(shè)計(jì)
- 【MOOC】法理學(xué)-西南政法大學(xué) 中國(guó)大學(xué)慕課MOOC答案
- 遼寧省普通高中2024-2025學(xué)年高一上學(xué)期12月聯(lián)合考試語(yǔ)文試題(含答案)
- 儲(chǔ)能運(yùn)維安全注意事項(xiàng)
- 2024蜀繡行業(yè)市場(chǎng)趨勢(shì)分析報(bào)告
- 電力法律法規(guī)培訓(xùn)
- 北京交通大學(xué)《成本會(huì)計(jì)》2023-2024學(xué)年第一學(xué)期期末試卷
- 2024年世界職業(yè)院校技能大賽“智能網(wǎng)聯(lián)汽車(chē)技術(shù)組”參考試題庫(kù)(含答案)
- 【課件】校園安全系列之警惕“死亡游戲”主題班會(huì)課件
- 化工企業(yè)冬季安全生產(chǎn)檢查表格
- 2024年工程勞務(wù)分包聯(lián)合協(xié)議
- 蜜雪冰城員工合同模板
評(píng)論
0/150
提交評(píng)論