- 第一步建立数据库
- 很多教程里都会写到如何建立数据库,但我一直没学会,这里我用的是vs2013,数据库用的是sql server2008(其实只要是微软的数据库都差不多)
- 1.打开VS2013,新建->新建项目->MFC应用程序->下一步->基于对话框程序->(finish)完成
- 2.在StdfAx.h中导入windows动态链接库,一般位置是在C:\Program Files\Common Files\System\ado,找到msado15.h在StdfAx.h的最后写上导入语句如下:
- #import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF") //导入计算机的动态链接库
- (其中rename("EOF","adoEOF")是将系统的EOF重命名为adoEOF以免在调用时发生冲突)
- 3.初始化ADO COM
- AfxOleInit();//初始化ADO COM(这是最简单的初始化方法)
- 4.定义连接集和数据集并进行初始化
- _ConnectionPtr m_pConnectionB;//定义连接数据库//(在***Dlg.h的public中定义)
- _RecordsetPtr m_pRecordsetB;//定义记录集 //(在***Dlg.h的public中定义)
- m_pConnectionB.CreateInstance(__uuidof(Connection));//初始化连接集对象//(在对话框应用程序中初始化)
- m_pRecordsetB.CreateInstance(__uuidof(Recordset));//初始化数据集对象 //(在对话框应用程序中初始化)
- 5.定义连接字
- CString strCon = _T("Provider=SQLOLEDB.1;Password=123456;Persist Security Info=True;User ID=sa;Initial Catalog=仓山区信息表;Data Source=(local)");
- (连接字的获取可以参考这个方式,当然也有方式自己获取,因为网上很多这种教程,所以在这里就不赘述了)
- try //连接可能出错,如果出错将会提示
- m_pConnectionB->Open((_bstr_t)strCon, _T(""), _T(""), adModeUnknown);//连接数据库
- }
- catch (_com_error &e)
- {
- AfxMessageBox((LPCTSTR)e.Description());
- m_pConnectionB = NULL;
- return TRUE;
- }
- catch (...)
- {
- AfxMessageBox(_T("未知的错误!"));
- m_pConnectionB = NULL;
- return TRUE;
- }
- 到这里我们已经连接好数据库了,接下来是要在TCP服务器端中调用数据库来验证客户登录的信息是否正确
- 根据TCP Socket通信原理,步骤如下,而要在客户端能验证账户和密码,方法是在客户端向服务端发送一个账户和密码的字符串,服务器接收到这个字符串之后调用数据库查看是否有这个用户,有的话允许登陆否则不允许!
- 我考虑的方法是服务器接收到客户端发过来的数据之后,
- 1.经过一系列动作把用户名和密码提取出来;
- 2.提取出来之后调用数据库的查询语句查询数据库中是否有该用户名,如果没有则提示该用户名不存在,并且关闭登陆程序
- 3.如果存在该用户名,那么就要利用该用户名得到一个数据集,然后再利用该数据集监测该用户名对用的密码是否和提取出来的密码相同,如果相同,则登陆成功,否则提示账户名或密码错误,并且终止登陆程序!
- 具体代码如下:
- TCHAR flsql[1024] = { 0 };//数据库语句变量
- _stprintf_s(flsql, _T("select *from dbo.USERS where Name = '%s'"),strName);//定义要执行的数据库语句,这里用where查询的语句查询符合截取出来用 户名的数据。
- printf("连接数据库\n");
- m_pRecordsetB->Open((_variant_t)flsql,dlg->m_pConnectionB.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText);//打开数据库获得符合条件 记录集
- printf("打开数据库");
- if (m_pRecordsetB->adoEOF) //如果没有符合条件的记录集
- {
- printf("记录集出错\n");
- int i, n;
- for (i = 0; i<dlg->m_list.GetItemCount(); i++)
- {
- n = atoi(dlg->m_list.GetItemText(i, 0));//将读取的字符串连接序号转换成int
- if (n == msgcount)//找到连接号
- {
- break;
- }
- }
- send(dlg->msgsock[n], "该用户名不存在!", 30, 0);
- m_pRecordsetB->Close();//关闭记录集
- //AfxEndThread(0);//关闭线程
- }
- else
- {
- //name = m_pRecordsetB->GetCollect(_T("Name"));//从数据集对象中获得Name
- password = m_pRecordsetB->GetCollect(_T("Password")); //从数据集对象中获 得Password
- //stryName = (LPCTSTR)_bstr_t(name);//将字符型转换为字符串型
- stryPassword = (LPCTSTR)_bstr_t(password);//将字符型转换为字符串型
- if (strcmp(stryPassword, strPassword) != 0)//如果密码符合
- {
- //AfxMessageBox(_T("用户名或密码错误,请检查!"));
- int i, n;
- for (i = 0; i<dlg->m_list.GetItemCount(); i++)
- {
- n = atoi(dlg->m_list.GetItemText(i, 0));//将读取的字符串连接序号转换成int
- if (n == msgcount)//找到连接号
- break;
- }
- send(dlg->msgsock[n], "用户名或密码错误,请检查!", 30, 0);
- //AfxEndThread(0);//关闭线程
- }
- else
- {
- printf("\n有新数据包到达,截取数据为:%s,%s\r\n", strName, strPassword);
- }
- m_pRecordsetB->Close();//关闭记录集
- }
- 结果如下图;