聊天程序客户端的设计与实现Word文件下载.docx
- 文档编号:16737417
- 上传时间:2022-11-25
- 格式:DOCX
- 页数:26
- 大小:172.87KB
聊天程序客户端的设计与实现Word文件下载.docx
《聊天程序客户端的设计与实现Word文件下载.docx》由会员分享,可在线阅读,更多相关《聊天程序客户端的设计与实现Word文件下载.docx(26页珍藏版)》请在冰豆网上搜索。
在VisualC++环境下,利用Microsoft的基本类库MFC(MicrosoftFoundationClassLibrary),可以使用完全的面向对象的方法来进行Windows95/98/NT应用程序的开发,使得Windows程序员从大量的复杂劳动中解放出来,体会到真正的程序语言的强大功能和良好的灵活性。
VisualC++编程是一个面向对象的程序设计方法。
同传统的结构化程序设计方法相比,它缩短软件的研制时间,提高软件的开发效率,使程序员可以更好地理解和管理庞大而复杂的程序。
面向对象的程序设计吸取了结构化程序设计的精华,它利用了人们根据对事物分类和抽象的思想,引入了类和对象的概念,具有封装性(数据抽象)、继承和多态的特点。
与结构化程序设计不同的是,面向对象程序设计是用类抽象代表现实的实体,用类之间的继承关系表示程序设计的抽象过程。
函数只是对数据的操作,没有数据的概念,而类是数据和数据操作的集合,由于面向对象的程序设计方法非常近现实,所以越来越流行。
VisualC++中集成了大量的最新技术,如ActiveX、COM等技术[1],程序开发人员可以紧紧地把握住软件开发技术发展的方向,开发出功能强大的应用程序。
VisualC++还提供了丰富的技术资源,MSDN(MicrosoftDevelopNetwork)提供了强大的联机帮助支持,同时还可以通过访问Microsoft的网上站点来获得最新的技术文档。
第二章技术背景
2.1客户机/服务器技术
在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户机/服务器模式(client/server),即客户向服务器提出请求,服务器接收到请求后,提供相应的服务[2]。
客户机/服务器模式的建立基于以下两点:
首先,建立网络的起因是网络中软硬件资源、运算能力和信息不均等,需要共享,从而造就拥有众多资源的主机提供服务,资源较少的客户请求服务这一非对等作用。
其次,网间进程通信完全是异步的,相互通信的进程间即不存在父子关系,又不共享内存缓冲区,因此需要建立一种机制为希望通信的进程间建立联系,为二者的数据交换提供同步,这就是基于客户机/服务器模式的TCP/IP。
2.2TCP通讯技术
TCP,面向连接的可靠的传输协议。
利用TCP协议进行通信时,首先要通过三步握手,以建立通讯双方的连接。
一旦连接建立好,就可以进行通信了[3]。
TCP提供了数据确认和数据重传的机制,保证了发送的数据一定能到达通信的对方。
这就与打电话一样,首先要拨打对方的电话号码以建立连接,一旦电话拨通,连接建立之后,你所说的每一句话都能够传送到通话的另一方。
2.3Socket通讯技术
套接字(Socket)是一种双向的通信接口,可以通过这个端口与任何一个具有Socket端口的计算机通信,套接字是网络通信的基础。
Socket在Windows以句柄的形式被创建。
使用Socket进行网络通信必须包含下面的几种信息:
双方认可的协议,本地主机的IP地址,本地进程的协议端口,对方主机的IP地址,对方进程的协议端口。
Socket可分为:
(1)数据报套接字(DatagramSockets)——对于在TCP/IP上实现的WinSock,数据报套接字使用用户数据报协议(UDP)。
数据报套接字提供了一种不可靠的、非连接的数据包通信方式。
(2)流式套接字(StreamSockets)——流式套接字使用传输控制协议(TCP)。
流式套接字可以将数据按顺序无重复地发送到目的地,它提供的是一种可靠的、面向连接的数据传输方式。
不管是对单个的数据报,还是对数据包,流式套接字都提供了一种流式数据传输。
VC++对网络编程的支持有socket支持,Winlnet支持,MAPI和ISAPI支持等。
其中WindowsSocketsAPI是TCP/IP网络环境里,也是Internet上进行开发最为通用的API。
最早美国加州大学Berkeley分校在UNIX下为TCP/IP协议开发了一个API,这个API就是著名的BerkeleySocket接口(套接字)[4]。
在桌面操作系统进入Windows时代后,仍然继承了Socket方法。
从表2-1可以看出,主要的WinSockAPI函数有哪些。
表2-1WinSockAPI函数
函数
功能
WSAStartup()
连结应用程序与WindowsSocketsDLL的第一个函数
WSACleanup()
结束WindowsSocketsDLL的使用
socket()
建立Socket
closesocket()
关闭某一Socket
bind()
将一本地地址与一个SOCKET描述字连接在一起
Listen()
设定Socket为监听状态,准备被连接
accept()
接受某一Socket的连接要求,以完成面向连接的客户端Socket的连接请求
connect()
要求连接某一Socket到指定的网络上服务端
recv()
从面向连接的Socket接收信息
Send()
使用面向连接的Socket发送信息
WSAAsyncSelect()
要求某一Socket有事件(event)发生时通知使用者
2.4Socket编程
MFC是对API的封装,MFC针对WinSockAPI封装了两个类:
CAsyncSocket和CSocket。
因此,使用这两个类进行Socket网络程序的编写会比使用API方便一些[5]。
MFC中Socket相关类的继承关系如图2-1所示。
CAsyncSocket对WinSockAPI进行了较低程度的封装,缺省情况下建立的Socket是异步操作方式,即非阻塞的,因此一些阻塞操作,需要自己动手完成。
另外,由于它对API的封装程度不高,以前在WinSockAPI中需要自己完成的工作(比如:
字节顺序的转换),仍然需要自己完成。
当然有许多程序员喜欢使用该类甚至WinSockAPI,原因是这些方法具有很大的灵活性,给程序员以较大的发挥空间。
图2-1MFC中Socket相关类的继承关系
为了给程序员提供更方便的接口以自动处理网络通信中的一些任务,MFC在CAsycnSocket类的基础上派生了CSocket类,它提供了比CAsyncSocket更高层的WinSockAPI接口。
CSocket的网络操作是同步方式,即阻塞式的。
CSocket建立的Socket不是阻塞的,而是对非阻塞的Socket进行处理后实现的阻塞操作。
在阻塞任务执行过程中,Windows线程的消息循环仍然有效,也就是说CSocket类的阻塞操作不影响Windows的消息循环。
第三章总体设计
3.1界面设计
在界面设计方面,本系统遵循了以下几点原则:
(1)Windows的统一界面风格;
(2)标准的图标风格设计,统一的构图布局,统一的色调、对比度、色阶;
(3)图片风格一致;
(4)提示信息、帮助文档文字表达遵循的开发原则。
3.2功能模块划分
本系统基于客户端/服务器基本原理,包含了客户端与服务器端两大功能模块,笔者主要负责客户端的开发,以下仅对客户端的功能模块进行介绍。
3.2.1登陆模块
登陆模块的实现过程有下面几个步骤:
(1)获取用户名,用户选择的头像,服务器的IP地址和端口号的信息;
(2)确认登陆后初始化,创建套接字,连接服务器,向服务器发送用户登陆信息,使其他在线用户得到本用户上线的消息;
(3)初始化过程中显示在线好友,并且对用户的好友上、下线进行管理。
3.2.2聊天模块
1.发送信息模块
聊天模块中,发送信息模块的实现过程有下面几个步骤:
(1)用户选择一个好友为聊天对象;
(2)识别是否已经与此好友处于聊天状态(有对应的聊天对话框打开),已处于聊天状态的,将该对话框显示到前台,未处于聊天状态的,创建一个新的对话框;
(3)用户按下发送按钮后,将聊天内容发送出去(服务器接收);
(4)在本地即时聊天内容显示的编辑框中添加发送的内容。
2.接收信息模块
聊天模块中,接收信息模块的实现过程有下面几个步骤:
(1)判断接收到信息的类型,是否为好友发来信息;
(2)若该好友第一次发送信息(没有与此好友聊天的对话框),提示用户有新的消息;
(3)用户按下查看消息的提示后,创建新的对话框,加到对话框链表中并显示该对话框,如果已经和此好友处于聊天状态,直接将对应对话框调到前台;
(4)在对应的对话框中显示传递过来的消息。
3.2.3聊天记录管理模块
聊天记录管理模块的实现过程有下面几个步骤:
(1)用户请求查看聊天记录,向服务器发送请求;
(2)服务器向用户发送对应的聊天记录,客户端接收信息,识别发送的信息为聊天记录;
(3)显示聊天记录;
(4)如果用户按下保存聊天记录按钮,则保存聊天记录。
第四章主要功能模块详述
4.1系统总述
本论文设计的聊天程序的基本思想是将所有的信息发送给服务器,服务器根据查看信息结构体中的接收方,再转发给接收用户。
因此,程序的正常运行是建立在用户与服务器建立好连接的基础上的。
在用户登陆前,首先要保证服务器端启动。
4.1.1贯穿整个设计的两个类
CMainSocket类与Message结构体贯穿于整个程序,是整个程序都用到的两个类。
CMainSocket:
CMainSocket类基于CSocket类,继承了套接字的最基本功能,其主要作用为向服务器端发送信息。
在其他的几个类中,向服务器发送消息时,都用到CMainSocket类的对象。
Message:
Message结构体是客户端与服务器端通信的基本单元,包含了发送方,发送对象等多种信息,其定义为:
structMessage
{public:
intiType;
//信息类型
intiSubType;
//信息次类型
charstrName[20];
//发送方名称
charstrClientName[20];
//接收方名称
charstrContent[1024];
//信息内容
intiImage;
};
iType与iSubType分别为信息的类型和次类型,用于标记信息为何种类型(如服务器系统信息、用户聊天信息);
strName为发送方名称,strName是用于鉴别用户的标识;
strClientName为接收方名称;
strContent为传送消息的具体内容;
iImage为发送方头像。
Message为客户端与服务器端通讯的基本单位,所以Message的大小需要固定,在选择strName等类型的时候,都用了char的数组,没有使用CString。
4.1.2客户端接收信息的流程
整个程序是以服务器与客户端之间的通信事件而驱动的,本程序划分为三大模块,但最基础的都是得到服务器传来的消息,对消息进行判别再分别交给不同模块进行处理。
本设计的接收消息过程很抽象,笔者在对设计详述之前首先将客户端接收消息的过程提纯出来,其示意图如图4-1所示。
事先已对套接字和端口进行过绑定,一旦端口有数据来到,就会触发CMainSocket对象的CMainSocket:
:
OnReceive()函数。
OnReceive()函数中调用的Receive()函数就可以得到端口进来的以Message结构体封装的消息。
再将Message的内容作为WM_RECEIVEMESSAGE的WPARAM参数发送。
WM_RECEIVEMESSAGE为自定义的消息,CMyQQClientDlg的OnReceiveMessage()为此消息对应的消息处理函数。
OnReceiveMessage()函数处理从wParam参数中传送来的以Message结构体封装的消息内容,针对不同的消息类型进行不同的处理。
在以下的每个模块中,会将OnReceiveMessage()函数进行分解,各模块只针对自己的部分进行处理。
图4-1接收消息过程
4.2模块功能详述
4.2.1登陆模块
管理模块流程图如图4-2所示。
管理模块的功能实现最主要由CLoginLoad、CMyQQClientDlg两个类来实现。
在下文介绍具体功能时,会对两个对话框控件进行分析。
图4-2管理模块流程图
CLoginLoad:
CLoginLoad是用户登陆的对话框,基于CDialog类。
CloginLoad的登录对话框的界面如图4-3所示。
其主要功能是获取用户名、用户选择的头像等信息,并且填写服务器IP与端口号。
此对话框主要有两个按钮,登陆按钮和退出按钮。
用户输入昵称和密码后可按登陆按钮,如不想登陆按退出按钮退出程序。
图4-3CLoginLoad用户登陆界面
CMyQQClientDlg:
CMyQQClientDlg是用户登陆后显示好友列表的对话框,基于CDialog类,CMyQQClientDlg也是本程序最核心的对话框。
此对话框只响应用户双击图标的事件,双击后,创建聊天对话框,然后开始进行聊天。
CMyQQClientDlg对话框的界面如图4-4所示。
图4-4CMyQQClientDlg好友列表对话框
管理模块实现过程有下面几个步骤:
(1)在CMyQQClientDlg:
OnInitDialog()过程中创建CLoginLoad对话框。
CLoginLoad对话框完成获取用户名,用户选择的头像,服务器的IP地址和端口号信息的功能。
(2)确认登陆后程序开始初始化,创建套接字,连接服务器;
向服务器发送用户登陆信息,服务器得到该消息后,向所有在线用户发送该用户登陆消息,其他客户端对用户上线消息各自进行处理。
服务器还会向登陆用户发送在线用户的信息,登陆用户即可在好友列表中添加好友信息。
完成登陆并添加完好友信息之后的CMyQQClientDlg界面如图4-4所示。
(1)和
(2)的代码部分都在CMyQQClientDlg:
OnInitDialog()的函数中。
整个程序初始化过程最核心的函数即为CMyQQClientDlg:
OnInitDialog()。
BOOLCMyQQClientDlg:
OnInitDialog()
{
//创建一个CLoginLoaddlg的对话框
CDialog:
OnInitDialog();
CLoginLoaddlg;
If(dlg.DoModal()==IDOK)
{
//创建套接字
if(!
m_skMainSocket.Create())
AfxMessageBox("
创建错误!
"
);
EndDialog(IDCANCEL);
returnfalse;
}
//连接服务器
if(!
m_skMainSocket.Connect(dlg.m_Server,dlg.m_Port))
{
AfxMessageBox("
连接错误!
EndDialog(IDCANCEL);
returnfalse;
}
//获取用户输入的消息
MessagemsObj;
msObj.iType=FIRSTLOG;
msObj.iSubType=FIRSTTIME;
CStringstrName=dlg.m_Name;
intimage=dlg.m_image;
theApp.m_pMainWnd->
SetWindowText(strName);
intiLen=strName.GetLength();
lstrcpy(msObj.strName,strName.GetBuffer(iLen));
msObj.iImage=image;
strName.ReleaseBuffer();
//向服务器发送用户登陆消息
m_skMainSocket.Send(&
msObj,sizeof(Message));
m_skMainSocket.SetUserName(strName);
m_skMainSocket.SetImage(image);
else//如果用户选择取消按钮,退出程序
//创建抽屉控件,初始化好友列表
DWORDdwf=
CGfxOutBarCtrl:
fDragItems|CGfxOutBarCtrl:
fEditGroups|CGfxOutBarCtrl:
fEditItems
|CGfxOutBarCtrl:
fRemoveGroups|CGfxOutBarCtrl:
fRemoveItems|CGfxOutBarCtrl:
fAddGroups
|CGfxOutBarCtrl:
fAnimation|
fSelHighlight;
CRectrc;
GetClientRect(&
rc);
wndBar.Create(WS_CHILD|WS_VISIBLE,rc,this,IDC_LST_MENU,dwf);
wndBar.SetOwner(this);
imaLarge.Create(IDB_IMAGELIST,32,0,RGB(0,128,128));
imaSmall.Create(IDB_SMALL_IMAGELIST,16,0,RGB(0,128,128));
wndBar.SetImageList(&
imaLarge,CGfxOutBarCtrl:
fLargeIcon);
imaSmall,CGfxOutBarCtrl:
fSmallIcon);
wndBar.m_pClientSocket=&
m_skMainSocket;
wndBar.SetAnimationTickCount(20);
wndBar.SetAnimSelHighlight(200);
wndBar.AddFolder("
我的好友"
0);
returnTRUE;
}
在函数CMyQQClientDlg:
OnInitDialog()中首先创建登陆对话框CLoginLoad的模态对话框,如用户选择登陆,则创建套接字,连接服务器,并且向服务器发送该用户登陆的消息,最后初始化好友列表,进入等待状态。
添加好友列表的过程是通过CGfxOutBarCtrl的控件来实现的。
CGfxOutBarCtrl是腾讯QQ用于好友列表显示的控件,笔者直接拿来使用,方便的实现了好友的显示及管理。
好友上下线管理中服务器端与客户端之间的通信示意图如图4-5所示。
向服务器发送的消息:
用户登陆后会向服务器发送用户登陆的消息,代码部分在已在CMyQQClientDlg:
OnInitDialog()函数中。
用户关闭CMyQQClientDlg的事件即为下线,在CMyQQClientDlg:
OnClose()函数完成该功能。
图4-5服务器
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 聊天 程序 客户端 设计 实现
![提示](https://static.bdocx.com/images/bang_tan.gif)