资源描述
vc++多人对战平台系统毕业设计
———————————————————————————————— 作者:
———————————————————————————————— 日期:
2
个人收集整理 勿做商业用途
摘要
因特网的发展使人类进入了一个全新的世界,人与人之间可以远隔万里为了同一兴趣爱好而交流,做到了网络无国界,信息无国界。随着因特网的不断发展,网络游戏作为一个新的名词融入到了人们的日常生活当中。网络游戏来源于“onlinegame”,更直接的翻译是“在线游戏",亦即必须在大家联网而且都在线的时候,才能够团队互动,否则就属于单机游戏了.
网络游戏产业作为现代电脑电子技术的产物,正在以其独特的魅力在全世界的娱乐领域占据主流位置,我们在承认广大娱乐网民的选择空间狭小的同时,也必须明确的一点就是网络游戏本身所具有的强大的吸引力。网络游戏的吸引力主要在于,它在让玩家打发时间的同时,可以让人实现在显示生活中不能实现的理想,得到在显示中不能得到的东西。而且网游产业促动高科技技术不断升级,作为经济增长的一大支撑点,已经成为经济腾飞的“第四产业”.近年来,世界网络游戏市场高速发展。根据统计,全球网络玩家所占互联网人群的比例已经超过30%。网络游戏凭借其信息双向交流,速度快,不受空间限制等互联网有时,具有诱人的互动性、仿真性和竞技性,已经成为网络业盈利优厚的三大领域之一。网络平台的发展,为网络游戏奠定了坚实的“物质”基础。宽带的迅猛发展为网络游戏提供了“高速公路”,而专用游戏服务器则为网络游戏提供了容量巨大的“加油站”。前不久,网络游戏还被视为一个“高风险”的行业,但随着人们对网络游戏的重新认识,网络游戏正在恢复其应有的地位。
本文在基于VC++开发平台的多人对战平台系统的工作基础上采用基于B/S三层架构模式,选取VC++6。0作为开发工具,以Access2007为后台数据库,来实现多人对战平台的基本功能。
关键词:连连看、网络游戏、网络对战
目录
摘要 I
目录 II
第1章 绪论 1
1.1目的 1
1。2意义 1
1.3主要问题 1
1.4技术要求 1
1.5发展概况 1
1.6指导思想 2
第2章 系统解决方案的选择 3
2。1 C/S结构 3
2.2 三层架构 4
2。2.1什么是“三层架构” 4
2。2.2三层架构的优缺点 4
第3章 需求分析 5
3。1产品描述 5
3。2产品功能 5
3.3具体功能需求 6
3。4协议设计 9
3.4.1控制消息UDP数据包格式 9
3.4。2客户端到服务器端(C-〉S)UDP数据包 10
3。4。3服务器端到客户端 (S—>C)UDP数据包 11
3.4.4数据库设计 11
3.4。5详细设计 11
第4章 总体设计 12
4。1开发环境 12
4.2相关表设计图 12
第5章 详细设计 28
5。1用户注册功能 28
5。 2登录页面 38
5。3游戏大厅 45
5。4游戏房间 54
5.5游戏准备界面 63
5.6游戏界面 67
第6章 总结与展望 96
致谢 96
第1章 绪论
1。1目的
网络小游戏制作的目的是满足了人们休闲的需要,在紧张工作之余休闲类的小游戏能够给人带来最大程度的放松,也可以增进人们之间的交流,沟通,通过游戏还可以认识更多的朋友,也可以到达跨省、跨市,甚至跨国间人们互相娱乐的目的。
另外也通过本程序将两年来所学的专业知识和其他方面的知识融入到实际应用中。
1.2意义
通过此次课题的设计,掌握如何制作一个游戏软件,以及制作游戏软件的整个流程,制作游戏软件的步骤,为以后的就业工作打下基础。
1.3主要问题
开始制作游戏时,主要要解决的问题有以下几个方面:如何设置整个游戏的界面;如何控制连连看游戏中随机图片的生成且每种图片必须为偶数个;游戏开始后,判断鼠标两次点击的图片能否消去,即图片是否相同且图片之间路径的判断;如何连接网络上的两台计算机实现网络对战,互发消息,如何判断游戏是否结束以及输赢问题等.
1。4技术要求
网络中任意计算机当运行该游戏软件是,要有一台当服务器,如果要当服务器,则等待客户机的连接请求;如果要当客户机,则要主动去连接服务器.游戏中能正确判断鼠标两次点下的图片是否可以消去、能正确判断游戏是否已经结束和哪一方玩家胜出。还可顺利发消息给对方和接收对方发来的消息.
1.5发展概况
网络游戏正处于加速发展周期中,中国网络游戏市场迅速扩大,近三年的年均增长率超过100%.网络游戏的告诉发展,逐渐引起了我国政府的高度重视,信息产业部、文化部、新闻出版总属等相关部门都在积极推动各项市场监管和鼓励网络游戏产业发展的政策措施的出台,2003年网络游戏首次被正式纳入国家863计划,标志着我国网络游戏产业已经的到政府的充分重视。除外,在网络游戏产业发展的同时,有力带动了相关行业的发展,如软件、计算机、通信、电信运营、互联网等,根据统计,网络游戏能够带动10倍于自身产值的相关行业的发展.预计未来三年,中国游戏时常规模仍将保持60%以上的告诉增长,至2006年市场规模将接近100亿元,而多样的资本运作模式将成为网络游戏产业发展的重要推动力。同时,手机游戏、家用游戏机、游戏传媒、电子竞技等游戏周边行业也将快速发展起来。
1.6指导思想
按照软件开发的总过程进行设计,经历定义和计划、需求分析、软件设计、软件编码、软件测试等过程。
第2章 系统解决方案的选择
2。1 C/S结构
C/S (Client/Server)结构,即大家熟知的客户机和服务器结构。它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Server端来实现,降低了系统的通讯开销。目前大多数应用软件系统都是Client/Server形式的两层结构,由于现在的软件应用系统正在向分布式的Web应用发展,Web和Client/Server 应用都可以进行同样的业务处理,应用不同的模块共享逻辑组件;因此,内部的和外部的用户都可以访问新的和现有的应用系统,通过现有应用系统中的逻辑可以扩展出新的应用系统。这也就是目前应用系统的发展方向.
C/S结构的优点是能充分发挥客户端PC的处理能力,很多工作可以在客户端处理后再提交给服务器。对应的优点就是客户端响应速度快。
C/S架构软件的优势与劣势:
(1)应用服务器运行数据负荷较轻.最简单的C/S体系结构的数据库应用由两部分组成,即客户应用程序和数据库服务器程序。二者可分别称为前台程序与后台程序。运行数据库服务器程序的机器,也称为应用服务器.一旦服务器程序被启动,就随时等待响应客户程序发来的请求;客户应用程序运行在用户自己的电脑上,对应于数据库服务器,可称为客户电脑,当需要对数据库中的数据进行任何操作时,客户程序就自动地寻找服务器程序,并向其发出请求,服务器程序根据预定的规则作出应答,送回结果,应用服务器运行数据负荷较轻。
(2)数据的储存管理功能较为透明。在数据库应用中,数据的储存管理功能,是由服务器程序和客户应用程序分别独立进行的,前台应用可以违反的规则,并且通常把那些不同的(不管是已知还是未知的)运行数据,在服务器程序中不集中实现,例如访问者的权限,编号可以重复、必须有客户才能建立定单这样的规则。所有这些,对于工作在前台程序上的最终用户,是“透明”的,他们无须过问(通常也无法干涉)背后的过程,就可以完成自己的一切工作。在客户服务器架构的应用中,前台程序不是非常“瘦小",麻烦的事情都交给了服务器和网络。在C/S体系的下,数据库不能真正成为公共、专业化的仓库,它受到独立的专门管理.
(3)C/S架构的劣势是高昂的维护成本且投资大。首先,采用C/S架构,要选择适当的数据库平台来实现数据库数据的真正“统一",使分布于两地的数据同步完全交由数据库系统去管理,但逻辑上两地的操作者要直接访问同一个数据库才能有效实现,有这样一些问题,如果需要建立“实时”的数据同步,就必须在两地间建立实时的通讯连接,保持两地的数据库服务器在线运行,网络管理工作人员既要对服务器维护管理,又要对客户端维护和管理,这需要高昂的投资和复杂的技术支持,维护成本很高,维护任务量大。
2。2 三层架构
2。2.1什么是“三层架构"
三层架构(3-tier application) 通常意义上的三层架构就是将整个业务应用划分为:表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)。区分层次的目的即为了“高内聚,低耦合”的思想.所谓三层体系结构,是在客户端与数据库之间加入了一个“中间层”,也叫组件层。这里所说的三层体系,不是指物理上的三层,不是简单地放置三台机器就是三层体系结构,也不仅仅有B/S应用才是三层体系结构,三层是指逻辑上的三层,即使这三个层放置到一台机器上。三层体系的应用程序将业务规则、数据访问、合法性校验等工作放到了中间层进行处理。通常情况下,客户端不直接与数据库进行交互,而是通过COM/DCOM通讯与中间层建立连接,再经由中间层与数据库进行交互。
2。2。2三层架构的优缺点
优点:
(1)开发人员可以只关注整个结构中的其中某一层;
(2)可以很容易的用新的实现来替换原有层次的实现;
(3)可以降低层与层之间的依赖;
(4)有利于标准化;
(5)利于各层逻辑的复用.
缺点:
(1)降低了系统的性能.这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成.
(2)有时会导致级联的修改。这种修改尤其体现在自上而下的方向.如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。
第3章 需求分析
3.1产品描述
本产品是一款网络游戏。系统由服务端与客户端两个程序构成。采用C/S构架方式实现。服务端主要业务:提供客户端请求的服务、中转游戏数据等。而客户端提供友好的人机交互方式,供用户游戏平台,主要实现了最多6人一起游戏,按照以下顺序实现:进入游戏大厅、准备开始游戏,如果有3个以上的客户端预备开始游戏,而限定时间内又没有新的客户端准备开始,服务端就要求客户端开始游戏的倒计时,倒计时完成后,各玩家开始游戏。在游戏过程中,各玩家可以看到其它玩家的游戏进度的缩略图,但不允许增加新玩家,其它没有游戏的玩家只可以旁观游戏
3。2产品功能
模块
功能
说明
服务端
玩家信息管理
积分管理
在线用户管理
游戏桌子管理
游戏棋盘管理
信息中转管理
客户端
注册新玩家
登陆功能
大厅浏览功能
准备与自动搜寻游戏功能
游戏旁观功能
各玩家地图缩略图
积分排行
连连看游戏规则
3。3具体功能需求
3。3.1服务器端: 玩家信息管理
引言:该功能实现玩家基础数据管理,包括玩家的游戏ID、姓名、密码、昵称、性别、生日、联系电话.这些数据是由客户端输入,玩家提交信息后,通过网络传输到服务端,服务端验证合法性后,自动生成一个新的游戏ID,告诉客户端,并将该玩家的一系列信息存入对应数据库表中。
输入
处理
输出
1. 游戏ID
2. 姓名
3. 昵称
4. 密码
5. 性别
6. 生日
7. 联系电话
1、 游戏ID是服务端自动生成给玩家的游戏编号,玩家登陆时用该编号登陆(编号位数不限,可以为1位也可以为任意位数值)
2、 姓名与昵称长度都不能超过8位,可以为字母 空格 汉字。
3、 密码长度5位,必需给出确认密码的输入 (不限定字符,可为任意字符)
4、 性别:男、女
5、 生日形如:**年**月**日
6、 联系电话:7位或8位或11位或12位(12位时第一个数字必需是0)
1、 所有输入不按规则输入,均给出相应错误提示,提示要有针对性
2、 如果两次密码输入不一致,给用户一个友好提示,要求改正
3、 密码用‘*'输出
3.3.2 服务端:积分管理功能
引言:服务端必需在每次游戏结束后,按各玩家游戏的进度情况,评出6个等级出来,分别加分6、3、1、0、—1、—2,并在玩家积分表加入对应的积分值,并在客户端能查看出积分排行情况,列出前10名的玩家信息。积分表包含:游戏ID(连连看游戏ID值暂定为1000)、玩家ID、积分
输入
处理
输出
1、 各玩家游戏的进度
1、服务端要求统计出各玩家所得分值
1、服务端应将该次游戏的各玩家得到累计到对应积分表中
2、 客户端能查看积分在前10名的玩家排行榜
3.3。3服务端:在线用户管理
引言: 服务端必需在列表视图里显示当前在线玩家,某玩家上线或下线必需实时更新列表。该列表内容包括玩家ID、昵称、玩家状态(空闲、旁观、正在游戏)
输入
处理
输出
实时更新在线用户列表,及相应玩家状态
3。3。4服务器端:游戏桌子管理功能
引言:游戏桌子数量暂定为1张,共6个位置,至少要3个人坐不同位置才可以开始游戏。服务端当监控到该桌子数量玩家数有3个以上,并在10秒内没有新玩家坐下,即可通知各坐下的客户端开始倒计时,开始倒计时后不允许新玩家再坐下空位置。如果各玩家主动都提出开始游戏,则可不用倒计时直接开始游戏。
3。3.5服务器端:游戏棋盘管理
引言: 开始游戏提交后,服务端随机生成本次游戏的棋盘布局数据,大小为12*8,发送给各玩家。(注:共有12*8=96项数据,数据取值暂定16种,每种数据出现6次)
输入
处理
输出
无
随机生成大小为12*8的棋盘布局数据
将棋盘数据发送给各玩家
3。3.6服务器端:信息中转管理功能
引言: 对各玩家的互相通讯的信息,都要经过服务器中转。包含游戏中通讯的数据、私聊、群聊等信息
3.3。7客户端:注册新玩家
引言:该功能在客户端输入新玩家信息,包括玩家的姓名、密码、昵称、性别、生日、联系电话。玩家提交信息后,通过网络传输到服务端,服务端能过后,通知客户端生成一个新的玩家ID,并在界面里提示出
输入
处理
输出
1. 姓名
2. 昵称
3. 密码
4. 性别
5. 生日
6. 联系电话
1、 姓名与昵称长度都不能超过8位
2、 密码长度5位,必需给出确认密码的输入
3、 性别:男、女
4、 生日形如:**年**月**日
5、 联系电话:7位或8位或11位或12位(12位时第一个数字必需是0)
1、 所有输入不按规则输入,均给出相应错误提示,提示要有针对性
2、 如果两次密码输入不一致,给用户一个友好提示,要求改正
3、 密码用‘*’输出
4、 注册成功与否要提示客户,如果成功则要给出新玩家的ID号
3。3.8客户端:登陆功能
引言:客户端启动程序后,要求客户输入玩家ID与密码,通过服务器验证后,如果存在该玩家且密码正确,则允许登陆,进入系统后,在界面上能直观看出当前玩家昵称。否则登陆失败提示登陆出错信息,不允许进入系统
输入
处理
输出
1、 玩家ID
2、 密码
1、 对输入的数据进行合法验证(数据格式验证)
1、登陆结果要给出提示,提示内容要人性化,合理
3。3.9客户端:大厅浏览功能
引言: 客户端进入系统后,可以浏览到当前游戏的大厅,及桌子数。目前只有一个桌子,因此在客户端能看到当前一张桌子,及桌子6个座位的入座情况即可.
3.3。10客户端:准备与自动搜寻位置功能
引言:客户端各玩家根据当前桌子的入座情况,选择一个空位置即可进入游戏状态,准备开始游戏。在入座过程中,有一玩家比你先坐下,则要提示已有玩家入坐该位置。
自动搜寻位置:该功能实现自动的搜索出一空位置,提示玩家是否入座该位置。
3.3。11客户端:游戏旁观功能
引言:该功能实现游戏桌子已经开始游戏后,其它非游戏中的玩家,可以进入旁观游戏状态,浏览到各玩家游戏进度情况。但不能任何方式干扰正在游戏玩家
3.3.12客户端:各玩家地图缩略图
引言:在游戏过程中,当前玩家可以看到其它玩家的游戏进度,用地图缩略图的方式清楚看到对方游戏状态。
3.3。13客户端:积分排行
引言:任何玩家都可以由主界面的功能链接,查看到当前全服积分提在前10名玩家信息,显示玩家信息只要主要信息即可
3.3。14连连看游戏规则与约定
引言:哪个玩家最快连完全图,则得分最高,只要一玩家连完全图,则游戏结束。此时服务端根据各玩家连接图片数量,排出该次游戏名次出来,并提示各玩家得分情况
重列功能:客户端提供连连看图片重列功能:重新放置剩下图片,可随机改变剩下图片位置与顺序,重列次数暂定为最多重列5次
连击次数统计:当连接图片一次与上一次连接时间相差在1秒内认为是连击,并要累计连接最大数,并显示在界面上。当断连击后,下次连击要显示出上次连击的最大数,如本次连击了两个,上次最大数为12次,则显示:2/12
3。3。15连连看游戏特效
引言: 连接线特效:两张相像的图被消时,要在这两张图之间爆破连线(模仿QQ连连看效果)
3.4协议设计
3。4。1控制消息UDP数据包格式
名称
内容
描述
长度
VERSION
01 00
协议版本
2
CMD_TYPE
Xx
命令类型(00,01)
1
KEYWORD
Xx
加密字段
1
COMMAND
Xx xx
命令代码
2
SEQNUM
Xx xx
数据包序号
2
UIN
Xx xx xx xx
发送方标识
4
PARAMETERS
可变
可选参数
可变
CMD_TYPE取值范围
值
含义
00
C—〉S
01
S-〉C
3.4。2客户端到服务器端(C->S)UDP数据包
名称
代码
描述
CMD_KEEPALIVE
0x01
学生在线保持
CMD_REG
0x02
用户注册
CMD_LOGIN
0x03
用户登录
CMD_SEND_LOG_DATE
0x04
向服务器请求在线列表
CMD_FANGJIAN_DATE
0x05
进入游戏房间
CMD_CLOSE_DATE
0x06
关闭游戏
CMD_KEEPALIVE
名称
内容
描述
长度
HOST
可变
主机名称
可变
MAC
Xx xx xx xx xx xx
MAC地址
6
3.4.3服务器端到客户端 (S—〉C)UDP数据包
名称
代码
描述
SRV_LOGIN_OK
0x01
登录成功
SRV_REG_OK
0x02
注册成功
SRV_QUNLIAO_DATE
0x03
群聊信息
SRV_GAME_OVER
0x04
游戏结束
SRV_EXIT_TUPIAN
0x05
离开桌子
SRV_YOUXI_KAISHI
0x06
游戏开始
SRV_ CHONGZHI
0x07
重置图片
3。4。4数据库设计
根据系统流程图对数据库进行设计(详细见第4章)。
3。4。5详细设计
进行了系统详细设计,并进行编码设计,完成了对多人对战平台(连连看)系统大部分功能模块的开发.(详细见第5章)。
第4章 总体设计
4.1开发环境
开发工具:Microsoft Visual C++ 6。0
数据库 :Microsoft Access 数据库
4.2相关表设计图
服务器类图
客户端类图
数据库表设计图:
用户明细表:
用户积分表
玩家在线状态表
在线状态明细表
数据库关系图
系统用例图
注册功能流程图
登录功能流程图
请求实时在线列表流程图
坐下位置流程图
准备开始游戏流程图
开始游戏流程图
重置图片流程图
小地图功能流程图
聊天流程图
实时更新图片流程图
第5章 详细设计
由于是客户机/服务器模式,因此下列的功能都将是服务器和客户端对应的功能一起讲解
5。1用户注册功能
1、注册如图5.1.1
图5。1。1注册
首先,我们先来查看如何获得用户输入的数据
为了保存用户的数据,我们需要定义变量进行接收:
CString m_username;
CString m_nicheng;
CString m_pass;
CString m_two_pass;
CString m_tel;
CTime m_date;
int m_men;
接下来是处理和打包数据:
先是判断用户是否有输入数据:
BOOL MyReg::CheckNull()
{
UpdateData();
if (m_username.IsEmpty())
{
MessageBox("用户名不能为空!”);
m_pEdit = (CEdit*) this—〉GetDlgItem(IDC_YONGHU);
m_pEdit->SetFocus();
return FALSE;
}
if (m_nicheng。IsEmpty())
{
MessageBox(”昵称不能为空!");
m_pEdit = (CEdit*) this-〉GetDlgItem(IDC_NICHENG);
m_pEdit—>SetFocus();
return FALSE;
}
if (m_pass。IsEmpty())
{
MessageBox(”密码不能为空!”);
m_pEdit = (CEdit*) this—>GetDlgItem(IDC_MIMA);
m_pEdit-〉SetFocus();
return FALSE;
}
if (m_two_pass。IsEmpty())
{
MessageBox("确认的密码不能为空!”);
m_pEdit = (CEdit*) this-〉GetDlgItem(IDC_QUERENMIMA);
m_pEdit->SetFocus();
return FALSE;
}
if (m_tel.IsEmpty())
{
MessageBox(”电话不能为空!”);
m_pEdit = (CEdit*) this—〉GetDlgItem(IDC_DIANHUA);
m_pEdit—〉SetFocus();
return FALSE;
}
if (m_men == —1)
{
MessageBox(”性别不能为空!");
m_pEdit = (CEdit*) this—>GetDlgItem(IDC_RADIO1);
m_pEdit—〉SetFocus();
return FALSE;
}
return TRUE;
}
如果有输入空的数据,则返回假,正确返回真。
之后是判断数据是否输入正确:
BOOL MyReg::CheckFull()
{
if (!CheckNull())
{
return FALSE;
}
if (m_pass。GetLength() != 5 || m_two_pass.GetLength() != 5)
{
MessageBox(”密码长度不正确!");
m_pEdit = (CEdit*) this->GetDlgItem(IDC_MIMA);
m_pEdit->SetFocus();
m_pass。Empty();
m_two_pass。Empty();
UpdateData(FALSE);
return FALSE;
}
if (m_pass != m_two_pass)
{
MessageBox("两次输入的密码不正确!");
m_pEdit = (CEdit*) this—>GetDlgItem(IDC_MIMA);
m_pEdit-〉SetFocus();
m_pass.Empty();
m_two_pass.Empty();
UpdateData(FALSE);
return FALSE;
}
if (m_tel.GetLength() == 7 || m_tel.GetLength() == 8 || m_tel。GetLength() == 11)
{
return TRUE;
}
else if (m_tel。GetLength() == 12)
{
if (m_tel.Left(1) != ”0”)
{
MessageBox(”你输入的电话的第一位不正确,请重新输入!!”);
m_pEdit = (CEdit*) this-〉GetDlgItem(IDC_DIANHUA);
m_pEdit—〉SetFocus();
m_tel.Empty();
UpdateData(FALSE);
return FALSE;
}
return TRUE;
}
else
{
MessageBox("你输入的电话的位数不正确,请重新输入!!”);
m_pEdit = (CEdit*) this—〉GetDlgItem(IDC_DIANHUA);
m_pEdit-〉SetFocus();
m_tel。Empty();
UpdateData(FALSE);
return FALSE;
}
return TRUE;
}
当数据都验证成功之后,将调用下面函数发送至服务器端
void MyReg::OnOK()
{
// TODO: Add extra validation here
if (!CheckFull())
{
return;
}
REG_DATE m_reg;
memset(&m_reg,0,sizeof(REG_DATE));
strcpy(m_reg。birthday,m_date.Format("%Y—%m—%d"));
strcpy(m_reg.nicheng,m_nicheng);
strcpy(m_reg。password,m_pass);
strcpy(m_reg.tel,m_tel);
strcpy(m_reg。user_name,m_username);
m_reg.sex = m_men;
char buf[sizeof(REG_DATE) + sizeof(int) + 1];
memset(buf,0,sizeof(buf));
sprintf(buf,"%04d”,REG);
char *p = buf;
p += 4;
memcpy(p,&m_reg,sizeof(REG_DATE));
sendto(MySocket::m_socket,buf,sizeof(REG_DATE) + sizeof(int) + 1,0,(sockaddr*)&MySocket::udp_addr,sizeof(sockaddr_in));//这里将数据发送到服务器
}
服务器端:服务器在接受到客户端的信息之后,将调用下面的函数进行处理:
void CMyDlg::Reg_date(LPPER_IO_DATA pData)
{
REG_DATE reg = *((REG_DATE*)(m_buf));
CString c_sql;
int n;
c_sql。Format("insert into account(用户名,昵称,密码,性别,生日,电话) values(’%s’,'%s’,'%s’,%d,'%s','%s’)",
reg.user_name,reg。nicheng,reg。password,reg.sex,reg.birthday,reg.tel);
LONG text = m_ado。JExecuteWithoutRecordset(c_sql); //这里调用ADO连接数据库
switch (text)
{
case 1:
{
RECORDSET rs = m_ado.JExecuteWithRecordset("select MAX(用户ID) as id from account”); if (rs != NULL)
{
while (!rs->rsEOF)
{
………
}
}
CString c_sql;
c_sql。Format(”insert into account_jifen(用户ID) values(%d)”,n);
m_ado.JExecuteWithoutRecordset(c_sql);
REG_DATE send_reg;
memset(&send_reg,0,sizeof(REG_DATE));
send_reg.id = n;
send_reg.flag = EXEC_OK;
char buf[sizeof(int) + sizeof(REG_DATE) + 1] = {0};
char* s = buf;
sprintf(buf,”%04d",REG);
s += 4;
memcpy(s,&send_reg,sizeof(REG_DATE));
sendto(m_sock。GetSock(),buf,sizeof(int) + sizeof(REG_DATE) + 1,0,(sockaddr*)&pData-〉addr,sizeof(sockaddr_in));
}
break;
default:
{
REG_DATE send_reg;
send_reg。flag = OTHER_ERROR;
char buf[sizeof(int) + sizeof(REG_DATE) + 1] = {0};
char* s = buf;
sprintf(buf,”%04d",REG);
s += 4;
memcpy(s,&send_reg,sizeof(REG_DATE));
sendto(m_sock.GetSock(),buf,sizeof(int) + sizeof(REG_DATE) + 1,0,(sockaddr*)&pData—〉addr,sizeof(sockaddr_in)); //这里将注册成功或失败的信息返回给客户端
}
break;
}
}
客户端: 接收到服务器端发送回来的信息之后将成功或失败的信息显示出来,如果失败,将需要用户继续输入,如果成功,将提示成功信息,并返回到登陆界面.
LRESULT MyReg::OnUserReg(WPARAM wParam,LPARAM lParam)
{
……………。.
{
CString str;
str。Format("注册成功\r\n登陆ID为:%d",m_reg。id);
MessageBox(str);
}
else
{
MessageBox("注册失败");
m_username = _T(”");
m_nicheng = _T(””);
m_pass = _T(”");
m_two_pass = _T(”");
m_tel = _T(”");
m_date = CTime::GetCurrentTime();
m_men = -1;
UpdateData(FALSE);
m_pEdit = (CEdit*) this—>GetDlgItem(IDC_YONGHU);
m_pEdit->SetFocus();
return 1;
}
MyGlobalVariable* m_glb = MyGlobalVariable::GetMyGlobalVariable();
::SendMessage(m_glb—>GetLoginHwnd(),USER_MSG,(unsigned int)&m_reg。id,NULL);
CDialog::OnOK();
return 0;
}
注册成功的界面
5. 2登录页面
1、登录页面如图5.1.2
图5.1。2登录截图
首先定义2个变量接受用户输入的账号和密码的信息,定义如下:
CString m_id;
CString m_mima;
当用户点击了登陆界面之后,将调用以下函数进行处理:
void MyLogin::OnOK()
{
// TODO: Add extra validation here
UpdateData();
LOGIN_DATE m_log;
memset(&m_log,0,sizeof(LOGIN_DATE));
m_log。user_name = atoi(m_id);
strcpy(m_log.password,m_mima);
char buf[sizeof(LOGIN_DATE) + sizeof(int) + 1];
memset(buf,0,sizeof(buf));
sprintf(buf,”%04d”,LOGIN);
char *p = buf;
p += 4;
memcpy(p,&m_log,sizeof(LOGIN_DATE));
sendto(MySocket::m_socket,buf,sizeof(LOGIN_DATE) + sizeof(int) + 1,0,(sockaddr*)&MySocket::udp_addr,sizeof(sockaddr_in)); //这里将用户输入的数据发送到服务器端
}
服务器端:当服务器收到用户提交的登录请求之后,将调用以下函数查询数据库并返回成功或失败的信息
void CMyDlg::Lonin_date(LPPER_IO_DATA pData)
{
LOGIN_DATE
展开阅读全文