服务器放弃了开始使用的ADO方式,改用了ODBC;调试了很久,不知道是因为什么原因,ADO方式始终连接不正常,后来改用API方式连接Mysql,也遇到了你问题。总之,才用ODBC方式连接也是不得已选择了我还在后面继续调试API方式直连,希望能够尽快完成。
我选择了MFC中 CDatabase 和 CRecordset 来完成数据库的连接。
为此写了一个类:
------------------------CMySQLReader.h----------------------------
#pragma once
#include <afxdb.h> #include <odbcinst.h>
class CMySQLReader { public: CMySQLReader(void); ~CMySQLReader(void);
VOID OpenConn(LPCSTR pstrfilename); void ReleaseData(); CRecordset* Execute(LPCSTR sql);
protected: CDatabase m_Database; CRecordset m_Recset; };
------------------------------------------------------------------
这个类负责了整个MYsql数据库的连接和命令的执行。期中 负责连接的函数是
VOID CMySQLReader::OpenConn( LPCSTR pstrfilename ) {
CString sSql; CString strConnection;
// 创建进行存取的字符串
strConnection="Provider=MSDASQL.1;DSN=mysql assword=54321 ersist Security Info=True;User ID=root;Data Source=test";
TRY { m_Database.Open(NULL, false, false, strConnection); }
CATCH(CDBException, e) { // 数据库操作产生异常时... AfxMessageBox("数据库连接出错: " + e->m_strError,MB_ICONERROR|MB_OK); } END_CATCH;
}
这样,我们通过ODBC和Mysql数据库进行了连接。
在这里,遇到了第一个难题,就是使用CDatabase连接数据库,用CRecordset 获取数据查询的时候,发现CRecordset ::Open()函数,只能进行查询操作,其他的操作,都会视为非法操作,这个地方很不理解,因为刚刚接触Mysql数据库编程,好多的地方都不是很明白,也许是我建立的数据库格式,或者别的问题吧。总之,在这里我大约卡了近8个小时,写了至少5种不同的与MySQL的连接方式,都不凑效,到后来一直没有找合适的解决方案,再次返回到CDatabase方式。 如果有这方面的大虾有幸看到了这行代码,请指点一二~小老鼠在此不胜感激!
后来,我放弃了CRecordset 方式查询,直接才用了CDatabase 的.ExecuteSQL(sql);方法,实现了插入,更新的操作,抬头看看窗外,正好看到一缕早晨的阳光柔柔的照进来,项目终于看到曙光了~
经过测试,这个类数据的插入都很正常。
下来,就是我们第二项要做的事情,建立我们的socket服务器;因为我们用的数据库CDatabase类是在FMC环境下的,所以我就采用了MFC里面的CAsyncSocket作为SOCKET。
这个类对于大多数人来说没有什么难的地方,我们把它放入一个基于对话框的MFC项目组中
这个类如下:
-------------------------MyEchoSocket .h---------------------------------
#pragma once
class MyEchoSocket : public CAsyncSocket { public: MyEchoSocket(void); virtual ~MyEchoSocket(void);
void SetParentDlg(CDialog *pDlg);
virtual void OnAccept(int nErrorCode); virtual void OnClose(int nErrorCode); virtual void OnConnect(int nErrorCode); virtual void OnReceive(int nErrorCode); virtual void OnSend(int nErrorCode); private: CDialog * m_pDlg; };
-----------------------------------------------------------------------------
类很好用,不过对于很多不太用MFC的人来说,数据写在什么地方是一个难题,我们这里列举几个主要的函数。
BOOL CMySQL_serverDlg::OnInitDialog() { CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码 m_DataRecord.OpenConn("test"); //设置数据库源 m_sockListener.SetParentDlg(this); //设置SOCKET m_sockConnected.SetParentDlg(this); SetWindowText("Flash_Game Server V0.1"); //设置标题 return TRUE; // 除非设置了控件的焦点,否则返回 TRUE }
void CMySQL_serverDlg::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码 // 服务器启动 UpdateData(TRUE); m_sockListener.Create(5050); if(m_sockListener.Listen()==FALSE) { AfxMessageBox("服务器启动失败"); m_sockListener.Close(); return; } m_status = _T("运行中.."); UpdateData(FALSE); SetWindowText("服务器已经启动"); }
void CMySQL_serverDlg::OnAccept() { if(m_sockListener.Accept(m_sockConnected)) { SetWindowText("用户连接成功..等待输入数据"); UpdateData(FALSE); }
else { AfxMessageBox("用户连接失败"); } }
void CMySQL_serverDlg::OnClose() { AfxMessageBox("用户断开连接"); }
void CMySQL_serverDlg::OnReceive() { char *pBuf =new char [1025]; CString strData; int iLen; iLen=m_sockConnected.Receive(pBuf,1024); if(iLen==SOCKET_ERROR) { AfxMessageBox("无法接收数据"); } else { strData = "INSERT INTO coord ( Point ) VALUES ('"; strData = strData + pBuf; strData = strData + "');"; m_DataRecord.Execute(strData); strData = "存入数据库" ; strData +=pBuf; SetWindowText(strData); delete pBuf; } }
服务器的源码放在里QQ群里面,如果有疑问的下载源码看。
|