分享
 
 
 

典型网络数据库系统软件设计

王朝vc·作者佚名  2006-01-17
窄屏简体版  字體: |||超大  

典型网络数据库系统软件设计

作者:∑阿强

下载源代码

一、概述

本系统为内部系统,帐户由管理员添加、管理;

分为两个组,User组和Boss组。Boss组的帐户可以发广播通知;

任意两个用户间可以互相通信;

数据库接口用DAO,网络通信用 CSocket+CSocketFile;

二、详细设计

1、数据库设计

本系统只是一个消息通信模型,这里的数据库设计比较简单。

ER图:

把ER模型转为关系模型,共两个表:

User (No , Name ,Password ,G#) 候选键:No 外键:G#

Group (G# , GroupName ,Demo ) 主键 :G#

2、消息格式设计

<1>、传送的消息共有5类------登录消息,验证返回消息,普通消息,用户列表消息,通知消息。定义一个枚举类型:

enum MSGTYPE {LOGIN , LOGINResponse , CHATTING , USERList , NOTICE};

<2>、定义消息类

class CMsg : public CObject

{

public:

int m_eType; //枚举类型,记录消息类型

CString m_strMsg; //消息

CMsg();

virtual ~CMsg();

void Serialize(CArchive &ar); //消息类系列化函数,发送和接受消息时用。

};

<3>、m_strMsg 为消息类中存放消息的成员,它的具体格式随着消息类型m_eType不同而不同。

m_eType

m_strMsg

LOGIN

呢称|密码

LOGINResponse

GOOD|欢迎!(BOSS) 或 FAILED|验证失败!

CHATTING

发给(来自)的用户名|消息内容

USERList

呢称1|呢称2|…|呢称n|END

NOTICE

ALL|消息内容 或 来自的用户|消息内容

m_strMsg中个内容用“|”隔开,用函数Decode(int n,CString strMsg) 获的相应的内容。

CString Decode(int n,CString strMsg)

{

int pos;

CString str;

for(int i=1;i<=n;i++)

{

pos=strMsg.Find ("|",0);

if(pos

<4>、消息发送接收的序列化函数

void CMsg::Serialize (CArchive &ar)

{

if(ar.IsStoring())

{

ar<<m_strMsg<<m_eType;

}

else

{

ar>>m_strMsg>>m_eType;

}

}

3、通信协议设计

验证。客户端发送LOGIN消息,服务器回应 LOGINResponse消息;

通信。客户端发送CHATTING 或 NOTICE 消息,服务器端根据接收到的消息,发送CHATTING,NOTICE或

USERList 消息。

4、服务器设计

<1>、建立工程

①、用MFC AppWizard(exe) 新建一个“单个文档”的工程;

②、在Step 2 of 6中,选 “查看数据库不使用文件支持”,点击“Data

Source..”按钮,然后在弹出的对话框中选 “DAO”类型,再浏览选择数据库文件Data.mdb. 按确定,再在弹出的窗口选User表;

③、点击Next到Step 4 of 6,选“windows

Sockets”。网络功能支持;

④、按“NEXT“,最后点击 “完成”;

<2>、在CSuperServerView中添加下列成员:

int m_iPort;//服务器端口

CSocketListen * m_pSocket; //监听套接字。

CSocketClient m_SocketClient[Max]; //跟客户端通信的套接字。

CArchive * m_pArOut; //发送消息时的序列化文档对象指针。

CArchive * m_pArIn; //接收消息时的序列化化文档对象指针。

CSocketFile * m_pSF; //套接字文件对象指针。

CMsg msg;//消息类对象

CString Decode(int n,CString strMsg); //消息的解码函数

void SendUserList();

bool CheckLogin(CSocketClient *pClient);

void MyReceive(CSocketClient *pClient);

void MyClose(CSocketClient *pClient);

void MyAccept();

<3>、CSuperServerView类的关键成员函数:

void CSuperServerView::MyReceive(CSocketClient *pClient)

{

m_pSF=new CSocketFile(pClient);

m_pArIn=new CArchive(m_pSF,CArchive::load);

msg.Serialize (*m_pArIn);

int i;

bool bOK=false;

switch(msg.m_eType )

{

case LOGIN: //处理用户登录。

{

m_pSF=new CSocketFile(pClient);

m_pArOut=new CArchive(m_pSF,CArchive::store);

msg.m_eType =LOGINResponse;

if(CheckLogin(pClient))

{

if(!pClient->m_bBoss)

{

msg.m_strMsg="GOOD|欢迎!";

bOK=true;

}

else

{

msg.m_strMsg="GOOD|BOSS";

bOK=true;

}

else

{

msg.m_strMsg="FAILED|验证失败!";

}

msg.Serialize (*m_pArOut);

m_pArOut->Flush ();

if(bOK) SendUserList();

break;

}

case CHATTING: //处理普通消息

{

for(i=0;i<Max;i++)

{

if(m_SocketClient[i].m_bBusy)

{

if(m_SocketClient[i].m_strName ==Decode(1,msg.m_strMsg))

{

m_pSF=new CSocketFile(&m_SocketClient[i]);

m_pArOut=new CArchive(m_pSF,CArchive::store);

msg.m_strMsg=pClient->m_strName+"|"+Decode(2,msg.m_strMsg);

msg.Serialize (*m_pArOut);

m_pArOut->Flush ();

break;

}

}

}

break;

}

case NOTICE: //处理广播消息。

{

msg.m_strMsg=pClient->m_strName+"|"+Decode(2,msg.m_strMsg);

for(i=0;i<Max;i++)

{

if(m_SocketClient[i].m_bBusy &&

m_SocketClient[i].m_strName != pClient->m_strName)

{

m_pSF=new CSocketFile(&m_SocketClient[i]);

m_pArOut=new CArchive(m_pSF,CArchive::store);

msg.Serialize (*m_pArOut);

m_pArOut->Flush ();

}

}

break;

}

}

}

void CSuperServerView::MyAccept()

{

for(int i=0;i<Max;i++)

{

if(!m_SocketClient[i].m_bBusy)

{

m_pSocket->Accept (m_SocketClient[i]);

m_SocketClient[i].GetView (this);

break;

}

}

}

void CSuperServerView::OnStartServer() //开始服务

{

m_pSocket=new CSocketListen(this);

m_pSocket->Create (m_iPort,SOCK_STREAM);

m_pSocket->Listen ();

m_staState.SetWindowText("正在监听......");

}

void CSuperServerView::OnStopServer() //关闭服务

{

if(m_pSocket) m_pSocket->Close ();

for(int i=0;i<Max;i++)

{

if(m_SocketClient[i].m_bBusy)

{

m_SocketClient[i].Close();

m_SocketClient[i].m_bBusy=false;

}

}

m_staState.SetWindowText("服务关闭");

}

数据库维护操作函数:

void CSuperServerView::OnButtonAdd() //添加帐户

{

CAddDlg dlg;

if(dlg.DoModal()==IDOK)

{

if(dlg.m_strName!="")

{

m_pSet->AddNew ();

m_pSet->m_Name=dlg.m_strName;

m_pSet->m_Password=dlg.m_strPwd;

m_pSet->m_G_=dlg.m_iG;

m_pSet->Update ();

UpdateData(FALSE);

}

}

}

void CSuperServerView::OnButtonDel() //删除帐户

{

m_pSet->Delete ();

m_pSet->MoveNext ();

if(m_pSet->IsEOF ())

m_pSet->MoveFirst();

UpdateData(FALSE);

}

void CSuperServerView::OnButtonModify() //修改帐户信息

{

CAddDlg dlg;

dlg.m_strName=m_pSet->m_Name;

dlg.m_strPwd=m_pSet->m_Password;

dlg.m_iG=m_pSet->m_G_;

if(dlg.DoModal()==IDOK)

{

if(dlg.m_strName!="")

{

m_pSet->Edit ();

m_pSet->m_Name=dlg.m_strName;

m_pSet->m_Password=dlg.m_strPwd;

m_pSet->m_G_=dlg.m_iG;

m_pSet->Update ();

UpdateData(FALSE);

}

}

}

void CSuperServerView::OnButtonFind() // 查找帐户

{

CFindDLG dlg;

if(dlg.DoModal()==IDOK)

{

if(dlg.m_strKey!="")

{

CString m_strName;

UpdateData(TRUE);

m_strName=dlg.m_strKey ;

if(m_pSet->IsOpen ())

m_pSet->Close ();

m_pSet->Open(AFX_DAO_USE_DEFAULT_TYPE,"SELECT * FROM user where Name=''"+m_strName+"''");

UpdateData(FALSE);

}

}

}

CSocketListen类中的接受事件函数OnAccept(int nErrorCode)。

void CSocketListen::OnAccept(int nErrorCode)

{

m_pView->MyAccept ();

CSocket::OnAccept(nErrorCode);

}

CSocketClient类中的接收消息函数。

void CSocketClient::OnClose(int nErrorCode)

{

// TODO: Add your specialized code here and/or call the base class

m_pView->MyClose(this);

CSocket::OnClose(nErrorCode);

}

CSocketClient类传递主窗口指针函数:

void CSocketClient::GetView(CSuperServerView *pView)

{

m_pView=pView;

}

<4>、程序界面

5、客户端设计。

<1>、建立一个名为Client,基与对话框的应用程序,在Step 2 of 6中选Windows Sockts支持,

<2>、在CClientDlg中添加成员。

CString Decode(int n,CString strMsg);

CMsg msg;

CMySocket * m_pSocket;

CArchive * m_pArOut;

CArchive * m_pArIn;

CSocketFile * m_pSF;

void MyReceive();

在CMySocket类中添加成员。

CClientDlg * m_pDlg;

CMySocket(CClientDlg *pDlg);

构造函数实现,获得指向主对话框的指针

CMySocket::CMySocket(CClientDlg *pDlg)

{

m_pDlg=pDlg;

}

<3>、关键函数

BOOL CClientDlg::OnInitDialog()

{

...

m_strHost="192.168.1.126";

m_iPort=1234;

UpdateData(FALSE);

GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(false);

Expand(0);

return TRUE; // return TRUE unless you set the focus to a control

}

void CClientDlg::OnLogin() //登录函数

{

UpdateData(TRUE);

GetDlgItem(IDC_BUTTON1)->SetWindowText("Wait");

m_pSocket=new CMySocket(this);

m_pSocket->Create();

int nTry=3,n;

do{

n=m_pSocket->Connect (m_strHost,m_iPort);

}while(n!=1 && nTry--);

if(n==1)

{

Sleep(2000);

m_pSF=new CSocketFile(m_pSocket);

m_pArOut=new CArchive(m_pSF,CArchive::store);

m_pArIn=new CArchive(m_pSF,CArchive::load);

msg.m_eType =LOGIN;

msg.m_strMsg =m_strName+"|"+m_strPwd;

msg.Serialize (*m_pArOut);

m_pArOut->Flush();

}

else

{

GetDlgItem(IDC_BUTTON1)->SetWindowText("Login");

GetDlgItem(IDC_BUTTON1)->EnableWindow(true);

AfxMessageBox("网络原因,没连上服务器!");

}

}

void CClientDlg::MyReceive() //接收消息函数

{

msg.Serialize (*m_pArIn);

int i=0;

CString str;

switch(msg.m_eType )

{

case LOGINResponse:

str=Decode(1,msg.m_strMsg);

if(str=="FAILED")

{

str=Decode(2,msg.m_strMsg);

m_pSocket->Close();

AfxMessageBox(str);

}

else

{

Expand(true);

GetDlgItem(IDC_BUTTON1)->SetWindowText("Login");

GetDlgItem(IDC_BUTTON1)->EnableWindow(false);

GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(true);

}

break;

case USERList:

str=Decode(++i,msg.m_strMsg);

m_ctrList.ResetContent();

while(str!="END")

{

if(str!=m_strName)

m_ctrList.AddString(str);

str=Decode(++i,msg.m_strMsg);

}

UpdateData(FALSE);

break;

case CHATTING:

MessageBox(Decode(2,msg.m_strMsg),"来自"+Decode(1,msg.m_strMsg)+"的消息:");

break;

case NOTICE:

MessageBox(Decode(2,msg.m_strMsg),"来自"+Decode(1,msg.m_strMsg)+"的通知:");

break;

}

}

CMySocket类中的事件函数OnReceive(int nErrorCode)。

void CMySocket::OnReceive(int nErrorCode)

{

m_pDlg->MyReceive (); //调用主窗口的接收函数

CSocket::OnReceive(nErrorCode);

}

、程序界面

①、登录界面

②、登录成功(左为User组用户登录后界面,右为Boss组的)

③、发送消息

④、接收消息

三、结束语

这是一个基于网络和数据库的系统模型,有点学习的价值。程序还有一些功能没完善的地方,并且存在一些Bug。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有