聊天室程序系统.doc_第1页
聊天室程序系统.doc_第2页
聊天室程序系统.doc_第3页
聊天室程序系统.doc_第4页
聊天室程序系统.doc_第5页
已阅读5页,还剩43页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

长沙电大毕业论文 第48页 共49页 长 沙 广 播 电 视 大 学毕 业 设 计聊天室软件实现指导老师:学生: 学号: 摘 要本课程设计实现类似于Windows操作系统自带的聊天程序。在课程设计中,系统开发平台为Windows XP,程序设计语言采用Visual C+,程序运行平台为Windows 98/2000/XP。在程序设计中,主要分别实现服务器端和客户端两部分程序。系统采用C/S结构,可以多人同时在线。程序通过调试运行,实现了设计目标,能够同时满足扫雷游戏初学者和高手的需要。关键词:聊天程序系统; 数据库;Visual C+6.0; SQL Server 2000AbstractThe course is designed to achieve similar to Windows operating system bringing chat program. In the curriculum design, system developing platform for Windows XP, programming language using Visual c + +, program operation platform for Windows 98/2000 / XP. In programming, mainly realized respectively the server and client two part program. System using C/S structure, can people online at the same time. Program through the post-sale service, realized the design goal, satisfies minesweeper beginners and superior needs.Keywords: chat program system; Database; Visual c + + 6.0, SQL Server 20001 绪论正如大多数聊天室一样,需要在一台计算机上运行服务器端程序,然后就可以在同一网络的其他计算机上运行客户端程序,登录到服务器上。一个聊天服务器和很多客户端进行通信,从而实现把来自不同的客户的聊天信息转交到所有其他的客户端。这样就形成一个采用C/S结构的可以多人同时在线的聊天室。同时本聊天室在设计时完成在线用户显示、私聊功能。私聊功能即是聊天信息只在私聊两方的计算机客户端上显示,其他客户端不显示。2 系统分析聊天程序系统提供了多个客户端的连接,可以允许多个用户同时在线。本设计主要对聊天室服务器和聊天室客户端两个方面进行实现,其功能:新用户登陆、更新在线用户列表、用户离开、私聊等。3.1功能简介根据用户的需求,要求系统需具有以下功能:(1) 聊天室服务器端实现功能:支持多个客户端的连接,一个聊天服务器和很多客户端进行通信。(2)接收客户端发送的信息,能分析信息的含义。A如果是新用户登录,则在服务器在线用户列表框中加入新用户昵称,并显示新用户进入信息提示,同时将更新在线用户列表发给所有客户端;B如果是用户离开,则在服务器在线用户列表框中删除此用户昵称,并显示用户离开信息提示,同时将更新在线用户列表发给所有客户端;C如果是私聊,聊天信息则显示在服务器聊天信息列表框中,同时将聊天信息仅仅发给私聊对象客户端;D如果是公开聊天信息则显示在服务器聊天信息列表框中,同时将聊天信息发给所有客户端。(3)服务器停止服务时,停止端口侦听,将停止服务信息发给所有客户端。二、聊天室客户端实现功能:(1)支持连接指定IP的聊天服务器。(2)私聊形式或公开形式发送聊天信息给聊天服务器。(3)接收服务器端发送的信息,能分析信息的含义。A如果是用户离开,则在在线用户列表框中删除此用户昵称;B如果是更新在线用户列表,则客户端重新显示在线用户。3.2系统特点A界面设计美观友好B规范、完善的基础信息设置C信息查询灵活、方便、快捷D系统运行稳定,安全可靠3.3 4 总体设计4.1 细化聊天室程序通信规程我们通过Socket发送一定格式的字符串来完成不同的操作。具体格式为:命令|参数|参数(1)新用户登录NEW_USER | 昵称(2)更新在线用户列表USERLIST | 昵称| 昵称| 昵称(3)用户离开CLOSEUSE | 昵称(4)私聊PrivChat| 私聊对象|私聊内容(含两方的昵称)注意:公开的聊天信息,则没有设置相应命令。在判断不是上述情况后,则就是公开的聊天信息。4.2 客户端工作流程(1)用户输入服务器端的IP和昵称后,单击连接聊天服务器按钮,客户端程序将建立一个连接套接字Socket与服务器端连接,如果成功,将昵称通过这个Socket发送到服务器端。(2)用户输入聊天信息后,单击发送信息按钮,通过这个Socket来发送给服务器。(3)用户如果单击“私聊”复选框,单击发送信息按钮后,先判断是否选择私聊对象,在发出“PrivChat| 私聊对象|私聊内容”。(4)当客户端单击“离开聊天室”按钮断开连接前向服务器发出“CLOSEUSE | 昵称”信息。4.3 服务器段工作流程(1)单击启动按钮,服务器端通过create()调用创建一个侦听套接字Socket后与指定的本地端口6767绑定,就可以在该端口进行侦听listen()。(2)如果有客户端连接请求,将触发侦听套接字的OnAccept事件,在事件处理函数中,创建新的连接套接字,用于与客户端的通信。并将该连接套接字Socket加入链表类CClientSocketList 指针List(&CCSL)所指的链表中。(3)每当一个连接套接字Socket 接收到信息,都将会触发服务器端对应的连接套接字的OnReceive事件。在OnReceive事件处理函数中,读取客户端发送的聊天信息,根据细化聊天室程序通信规程进行分析。如果是新用户登录或用户离开或公开聊天信息,则再把接收到的信息发送给每一个连接套接字Socket。如果是新用户登录或用户离开或私聊信息,则发给找到的私聊对象。(4)当客户端断开连接前向服务器发出“CLOSEUSE | 昵称”。服务器在OnReceive事件处理函数中在List所指的链表中释放该连接套接字,并同时将更新在线用户列表发给所有客户端。(5)当单击聊天室服务器“停止”按钮,停止端口侦听,广播聊天服务器停止消息,释放链表CCSL中套接字,清除服务器在线用户列表。4.3设计目标本系统是根据用户的实际需求而开发的,完全能够实现对用户的自动化管理,通过本系统可以达到以下目标:A系统运行稳定,安全可靠。B界面设计美观,人机交互界面友好。C信息查询灵活、方便、快捷、准确,数据存储安全可靠。D满足键盘和鼠标的双重操作,完全支持回车键。E采用多种方式查询数据。F操作员可以随时修改自己的口令。G对用户输入的数据,系统进行严格的数据检验,尽可能排除人为的错误。H,数据保密性强,为每个用户设置相应的权限级别。5 系统设计5.1 开发及运行环境软件要求操作系统:Windows2000/NT/XP/CE。数据库:SQL Server2000。5.2 聊天室客户端设计我们要做的客户端分需要输入一些登录信息,如下图1-1所示。其中上方有两个编辑框,其中一个输入用户昵称信息,另一个用于输入服务器IP地址信息。聊天室客户端窗口中间有两个列表框,一个显示用户聊天信息,另一个显示在线用户昵称信息。下方发言边的编辑框,用于输入聊天信息。两个按钮,一个用来发送信息,另一个用来关闭聊天室客户端窗口,退出聊天室。图1-1聊天室客户端窗口其实现过程:(1) 启动VC,利用MFC AppWizardEXE建立一个新的MFC程序,取名为ChatRoom,在MFC AppWizard Step 1的时候我们选择Dialog based,在Step 2时我们一定要选择上Windows Sockets选项,之后的几步我们就可以使用默认值了。聊天室客户端窗口是AppWizard生成的时候建立的。图1-2 MFC AppWizard Step 22创建连接套接字CClientSocket类按CTRL+W利用类向导添加一个基类为CSocket类的CClientSocket类,其中有一个很重要的是重载虚成员函数OnReceive(),它调用了主对话框的成员函数GetMessage来实现了立即显示从服务器获得的聊天信息到聊天室客户端窗口对话框中的功能。在CClientSocket类中添加一个指向对话框类的数据成员myDlg,NikeName。一个成员函数SetDlg。黑体为新增或修改过的代码。/ ClientSocket.h : header fileclass CChatRoomDlg;/ CClientSocket command targetclass CClientSocket : public CSocket/ Attributespublic:CChatRoomDlg * myDlg; /添加数据成员CString NikeName; /添加数据成员BOOL SetDlg(CChatRoomDlg *tmp); /添加一个成员函数/ Overridespublic:/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(CClientSocket)public:virtual void OnReceive(int nErrorCode);/ 重载的虚成员函数OnReceive/AFX_VIRTUAL.protected:;/ ClientSocket.cpp : implementation file#include stdafx.h#include ChatRoom.h#include ClientSocket.h#include ChatRoomDlg.h#include ChatRoomDlg.hCClientSocket:CClientSocket()NikeName=;myDlg=0;BOOL CClientSocket:SetDlg(CChatRoomDlg *tmp)myDlg=tmp;return true;void CClientSocket:OnReceive(int nErrorCode) myDlg-GetMessage();/调用了主对话框的成员函数GetMessage来显示聊天信息 CSocket:OnReceive(nErrorCode);3聊天室客户端窗口应用程序定义连接套接字CClientSocket类全局变量,传递到对话框中。/ ChatRoom.cpp#include ClientSocket.hCClientSocket curSocket; /全局变量curSocketBOOL CChatRoomApp:InitInstance() if (!AfxSocketInit() AfxMessageBox(IDP_SOCKETS_INIT_FAILED); return FALSE; AfxEnableControlContainer(); / Standard initialization #ifdef _AFXDLL Enable3dControls(); / Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); / Call this when linking to MFC statically #endifCChatRoomDlg dlg(&curSocket);m_pMainWnd = &dlg;curSocket.SetDlg(&dlg);int nResponse = dlg.DoModal();if (nResponse = IDOK)/ TODO: Place code here to handle when the dialog is/ dismissed with OKelse if (nResponse = IDCANCEL)/ TODO: Place code here to handle when the dialog is/ dismissed with Cancel return FALSE; 4需要在默认建立的主对话框上删除已有控件。聊天室客户端窗口对话框中的控件可以按表5-2建立。表5-2聊天室客户端控件属性表控件属性属性值控件成员变量变量类型标签Caption昵称编辑框m_IDC_EDIT_MESSAGECString标签Caption聊天室IP编辑框m_IDC_EDIT_ADDRESSCString按钮Caption连接聊天服务器IDConnect_Button编辑框m_IDC_EDIT_MESSAGECString列表框ID IDC_LIST1m_ ChatListCListBOXGroupBoxCaption在线用户列表列表框ID IDC_ USER m_USERCListBOX复选框ID IDC_CHECK1m_SLBOOL按钮Caption发送信息m_BNSendCButtonIDSend_Button按钮Caption离开聊天室m_ BNExitCButtonIDExit_Button其中m_IDC_EDIT_MESSAGE是发送信息框。修改对话框ChatRoomDlg的构造函数以及添加一个指向连接套接字的myServerSocket成员变量。/ ChatRoomDlg.h : header file#include ClientSocket.hclass CChatRoomDlg : public CDialog/ Constructionpublic:BOOL GetMessage();CChatRoomDlg(CClientSocket *tmp,CWnd* pParent = NULL); CClientSocket * myServerSocket;/ Dialog Data/AFX_DATA(CChatRoomDlg)enum IDD = IDD_CHATROOM_DIALOG ;CButtonm_BNExit;CButtonm_BNSend;CListBoxm_IDC_LIST_CHATBOX_CONTROL;CListBoxm_USER;CStringm_IDC_EDIT_MESSAGE;CStringm_IDC_EDIT_ADDRESS;CStringm_IDC_EDIT_NIKENAME;BOOLm_SL;/AFX_DATA;5对话框类中的函数聊天客户端CChatRoomDlg对话框初始化OnInitDialog()函数中添加代码实现“发送信息”按钮状态为无效;“离开聊天室”按钮状态为无效。添加客户端窗口的“连接服务器”按钮响应响应函数OnConnectButton()。它处理网络连接,如果连接服务器成功,发送成功登陆者昵称给服务器端接收,服务器端判断NEW_USER,知道新用户登陆,将更新在线用户列表字符串后,转发给各个客户端中显示。添加客户端窗口的“发送信息”按钮单击响应函数OnButton1()。它首先判断私聊复选框是否选中,如果选中则要保证选择私聊对象,将发出的信息以“PrivChat|+私聊对象+|登陆昵称+悄悄对+私聊对象+说+发送信息框的内容”的形式发给服务器端。服务器端判断首为PrivChat从而知道按私聊信息处理。如果未选中,则不含自定义格式。仅仅以“登陆昵称+说+发送信息框的内容”的形式发给服务器端。添加聊天室客户端窗口“退出聊天室”按钮的单击响应函数OnButton2()。它首先发送断开信息“CLOSEUSE|登陆昵称”后,关闭对话框。添加聊天室客户端窗口对话框的成员函数GetMessage()。它通过调用连接套接字的Receive()接收服务器端信息,根据细化聊天室程序通信规程来显示聊天信息或更新在线用户列表。/ ChatRoomDlg.cpp : implementation file#include stdafx.h#include ChatRoom.h#include ChatRoomDlg.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endifCClientSocket curSocket;CChatRoomDlg:CChatRoomDlg(CClientSocket *tmp,CWnd* pParent): CDialog(CChatRoomDlg:IDD, pParent)/AFX_DATA_INIT(CChatRoomDlg)m_IDC_EDIT_MESSAGE = _T();m_IDC_EDIT_ADDRESS = _T();m_IDC_EDIT_NIKENAME = _T();m_SL = FALSE;/AFX_DATA_INIT/ Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon = AfxGetApp()-LoadIcon(IDR_MAINFRAME); myServerSocket=tmp;BOOL CChatRoomDlg:OnInitDialog() /. SetIcon(m_hIcon, TRUE);/ Set big iconSetIcon(m_hIcon, FALSE);/ Set small icon/ TODO: Add extra initialization here m_BNSend.EnableWindow(FALSE); /发送信息按钮状态为无效m_BNExit.EnableWindow(FALSE); /离开聊天室按钮状态为无效return TRUE; / return TRUE unless you set the focus to a control void CChatRoomDlg:OnConnectButton() /“连接服务器”按钮响应函数/ TODO: Add your control notification handler code here UpdateData(TRUE); char *nikename,*address; int n; if (!myServerSocket-Create() myServerSocket-Close(); AfxMessageBox(网络创建错误!); return; n=m_IDC_EDIT_ADDRESS.GetLength(); address=new char(n+1); sprintf(address,%s,m_IDC_EDIT_ADDRESS.GetBuffer(n); addressn=0; n=m_IDC_EDIT_NIKENAME.GetLength(); nikename=new char(n+1); sprintf(nikename,%s,m_IDC_EDIT_NIKENAME.GetBuffer(n); nikenamen=0; if (!myServerSocket-Connect(address,6767) myServerSocket-Close(); AfxMessageBox(网络连接错误,请检查服务器地址。); return; m_BNSend.EnableWindow(TRUE); /发送信息按钮状态为有效 m_BNExit.EnableWindow(TRUE); /离开聊天室按钮状态为有效 myServerSocket-NikeName=nikename; /*发送新用户昵称 char message220; strcpy(message2,NEW_USER|); strcat(message2,myServerSocket-NikeName); if (myServerSocket-Send(message2,20) elseAfxMessageBox(网络传输错误!);void CChatRoomDlg:OnButton1() /发送按钮的函数/ TODO: Add your control notification handler code here int n; char message1000; CString to_name; UpdateData(TRUE); if(m_SL=TRUE) /私聊 if(m_USER.GetCurSel()=0) m_USER.GetText(m_USER.GetCurSel(),to_name); m_IDC_EDIT_MESSAGE=myServerSocket-NikeName+悄悄对+to_name+说+m_IDC_EDIT_MESSAGE; m_IDC_LIST_CHATBOX_CONTROL.AddString(m_IDC_EDIT_MESSAGE); m_IDC_EDIT_MESSAGE=PrivChat|+to_name+|+m_IDC_EDIT_MESSAGE; n=m_IDC_EDIT_MESSAGE.GetLength(); sprintf(message,%s,m_IDC_EDIT_MESSAGE.GetBuffer(n); messagen=0; else AfxMessageBox(没有选择私聊对象!); return ; else m_IDC_EDIT_MESSAGE=myServerSocket-NikeName+对大家说: +m_IDC_EDIT_MESSAGE; n=m_IDC_EDIT_MESSAGE.GetLength(); sprintf(message,%s,m_IDC_EDIT_MESSAGE.GetBuffer(n); messagen=0; if (myServerSocket-Send(message,n+1) m_IDC_EDIT_MESSAGE=; UpdateData(FALSE); else AfxMessageBox(网络传输错误!); void CChatRoomDlg:OnButton2() /离开按钮的函数/ TODO: Add your control notification handler code here/发送断开信息char message220;strcpy(message2,CLOSEUSE|);strcat(message2,myServerSocket-NikeName);if (myServerSocket-Send(message2,20)elseAfxMessageBox(网络传输错误!); myServerSocket-Close(); CDialog:OnOK();BOOL CChatRoomDlg:GetMessage()/显示聊天信息char buff2000;char name20;int count;count=myServerSocket-Receive(buff,2000); buffcount=0;char Flag10;for(int i=0;i8;i+) Flagi=buffi;Flag8=0; if(strcmp(Flag,USERLIST)=0)/新用户昵称列表 m_USER.ResetContent(); CString sTemp;int j=8;for(i=8;buffi!=0;i+) if(buffi=|)/昵称分割符号 for(int m=0;jClose(); ListenSocket.CCSL.Del(p);/释放链表中套接字 p=ListenSocket.CCSL.Head; ListenSocket.Close(); m_USER.ResetContent(); /清除服务器在线用户列表 m_IDC_BUTTON_START.EnableWindow(TRUE); 3创建侦听套接字CListenSocket类利用类向导创建一个基类为Csocket的CListenSocket类,在CListenSocket类中增加CClientSocketList CCSL变量;增加一个虚函数OnAccept。/ListenSocket.h头文件#include ClientSocketList.h /addclass CListenSocket : public CSocket / Attributes public: / Operations public: CClientSocketList CCSL; CListenSocket(); virtual CListenSocket(); / Overrides public: / ClassWizard generated virtual function overrides /AFX_VIRTUAL(CListenSocket) public: virtual void OnAccept(int nErrorCode); /AFX_VIRTUAL / Generated message map functions /AFX_MSG(CListenSocket) / NOTE - the ClassWizard will add and remove member functions here. /AFX_MSG / Implementation protected:; /CListenSocket.cpp具体内容如下#include stdafx.h#include ChatRoomServer.h#include ListenSocket.h#include ClientSocketList.h /add #include ClientSocket.h /add CListenSocket:CListenSocket()CListenSocket:CListenSocket()/ Do not edit the following lines, which are needed by ClassWizard.#if 0BEGIN_MESSAGE_MAP(CListenSocket, CSocket)/AFX_MSG_MAP(CListenSocket)/AFX_MSG_MAPEND_MESSAGE_MAP()#endif/ 0void CListenSocket:OnAccept(int nErrorCode) / TODO: Add your specialized code here and/or call the base class CClientSocket *tmp=new CClientSocket(&CCSL);/创建新的连接套接字 Accept(*tmp); CCSL.Add(tmp);/ 新的连接套接字加入套接字链表 CSocket:OnAccept(nErrorCode);4创建套接字链表类CClientSocketList利用类向导创建一个为生成客户Sockets队列的链表类CClientSocketList类,“Class Type”列表框选择Generic Class,如下图2-4所示。图2.4 基类Generic Class的派生类其中的成员变量Head指针是由CSocket直接派生出来的CClientSocket类。CClientSocketList类构造函数完成head初始化,同时增加将Socket加入链表队列Add()函数、仅仅向私聊用户发送信息OnlySend()函数、链表队列中删除Socket 的Del()函数、所有用户发送聊天信息Sends()函数。/CClientSocketList.h#include ClientSocket.hclass CClientSocketList public:BOOL Del(CClientSocket *); BOOL OnlySend(char *buff,int n,int who);BOOL Sends(char *buff,int n); BOOL Add(CClientSocket *); CClientSocket * Head;CClientSocketList();virtual CClientSocketList();/ClientSocketList.cpp #include stdafx.h#include ChatRoomServer.h#include ClientSocketList.h#include ClientSocket.h /addCClientSocketList:CClientSocketList()Head=0;BOOL CClientSocketList:Add(CClientSocket *add)/将Socket加入链表队列 CClientSocket *tmp=Head; if (!Head) Head=add; return false; while (tmp-Next) tmp=tmp-Next; tmp-Next=add; return true;BOOL CClientSocketList:Del(CClientSocket *d)/链表队列中删除Socket CClientSocket *p1=Head; CClientSocket *p2; if (!Head) return false; if (Head=d) Head=p1-Next;p1-Close();delete p1; return true; for(;p1-Next!=NULL;p1=p1-Next) if(p1-Next=d) p2=p1-Next; p1-Next= p2-Next; p2-Close(); delete p2; return true; return false;BOOL CClientSocketList:Sends(char *buff,int n)/所有用户发送信息 CClientSocket *curr=Head; while (curr) curr-Send(buff,n); curr=curr-Next; return true;BOOL CClientSocketList:OnlySend(char *buff,int n,int who)/仅仅向私聊用户who发送信息 CClientSocket *curr=Head; while (curr & who0) curr=curr-Next; who-; curr-Send(buff,n); return true;5创建连接套接字CClientSocket类利用类向导创建一个基类为Csocket类的CClientSocket类,CClientSocket类中增加CClientSocket(CClientSocketList *)构造函数;增加一个虚函数OnReceive()。它接收客户端的信息,根据细化聊天室程序通信规程来转发聊天信息或更新在线用户列表。三个指针变量List、Front、Next。/ClientSocket.h如下class CClientSocketList;class CChatRoomServerDlg;class CClientSocket : public CSocket/ Attributespublic: CChatRoomServerDlg * myDlg;/ Operationspublic:CClientSocket();CClientSocket(CClientSocketList *);virtual CClientSocket();/ Overridespublic: BOOL SetDlg(CChatRoomServerDlg *tmp);class CClientSocket : public

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论