《VC++课程设计报告.docx》由会员分享,可在线阅读,更多相关《VC++课程设计报告.docx(23页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Harbin Institute of Technology at Weihai瞟程双计报告部程名称:段计题VC+藻程设计聊天室程序设计院 系::计算机科学与技术系班 级:役计者:学 号:指导教师:设计时间:20n. 8.25哈尔滨工业大学(鼠海)chatDlg-GetMessage();定义一个 CMyChatDlg *类型的 chatDlg 变量作用就 在此体现。)if(type = LOGIN。)/收到服务器告知的更新用户的消息。(chatDlg-UpdateUser(); 调用 CMyChatDlg 类中的 UpdateUser 方法。)CSocket:OnReceive(nError
2、Code);)第三个函数:void CMyChatDlg:UpdateUser() 更新用户列表。char bufflOOO;memset(buff,0,sizeof(buff);m_pSocket-Receive(buff, sizeof(buff),0);CString user_info = buff;CString array100;/存放用户名称int b = 0;for( int i=0; iuser_info.GetLength(); i+ )拆分服务器端发来的用户名称,并用 ARRAY数组来存储。(if(i != (user_info.GetLength() - 1)判断是否已
3、经到达 UER_INFO 的尾端。(if ( user_infoi=,& )判断是否已经到一个昵称的结尾。(b+;用户力口一 else(array b = array b + user_infoi; 将一个用户名称拷贝到一个数组 单元中。)m_num.Format(n%d, b+l);将 INT 类型的 b 转换为 CString 类型。UpdateData(FALSE); 变量至 IJ 控件。m_UserList.ResetContent(); 置空列表框。for(int j=0; j 变量if(m_strMessage =(AfxMessageBox(不能发送空消息! ! ! ”);CEd
4、it *pEdit = (CEdit*)GetDlgItem(IDC_EDIT_MESSAGE);得到该控件类型 的对象地址。pEdit-SetFocus();调用成员函数设置焦点。return;)Header head;head.type = SEND_MESSAGE;head.len = m_strMessage.GetLength();CTime time = CTime:GetCurrentTime();得到系统当前时间。CString t = time.Format,%H:%M:%S”);设置时间格式。CString nikeName 二 theApp.m_strName;CStri
5、ng str =nikeName+ ” n + t + rn +m_strMessage;把要发送的信息者B 存储在这str变量中。m_pSocket-Send(char *)&head,sizeof(Header);发送头信息”。/ TODO: Add your control notification handler code hereif(m_pSocket-Send(LPCTSTR)str, str.GetLength。)/发送用户编辑的信息,并判 断Send函数的返回值。m_strMessage = nn;UpdateData(FALSE);/变量一控件的值CEdit *pEdit
6、= (CEdit*)GetDlgItem(IDC_EDIT_MESSAGE); pEdit-SetFocus();)else(AfxMessageBox(网络传输错误!);)第五个函数:BOOL CMyChatDlg:GetMessage()/ CClientSocket 对象中的 OnReceive 方法调 用。char buff1000;定义一个数组来接受消息。memset(buff,0,sizeof(buff);将数组全部初始化为 0。m_pSocket-Receive(buff, sizeof(buff),0);接受消息。CString strTemp 二 buff;strTemp +
7、= _T(nrnn);m_MessageList.ReplaceSel(strTemp);用strTemp变量中的内容替换消息显示框控 件的当前区域。return TRUE;)运行结果与分析(测试)打开服务器并初始化一个用户登陆服务器笊 Q聊天信息:唐皴 13:05:47 老师好/丁 X1人在线在线用户:唐毅发送客户端发送了一条消息退出第二个用户登陆ChatServer2人在线K ,_L_r服务器初始化成功2011-09-07 13:05:30:唐毅进入聊天室唐毅 13:05:47老师好2011-09-07 13:07:17:烟灰缸进入聊天室烟灰缸13:07:34呵呵在绷户 唐毅 烟灰缸殿 1
8、3:05:47师好灰缸 13:07:34唐老烟呵2人在线在线用户:唐毅 烟灰缸2人在线在线用户:唐毅 烟灰缸发送次 * 6聊天信息:烟灰缸13:07:34 呵呵退出两个用户之间聊天昵称为唐毅的用户离开聊天室0人在线服务器初始化成功2011-09-07 13:05:30:唐毅进入聊天室唐毅 13:05:47老师好2011-09-07 13:07:17:烟灰缸进入聊天室烟灰缸13:07:34呵呵2011-09-07 13:07:51:唐毅离开聊天室2011-09-07 13:08:06:烟灰缸离开聊天室关闭月艮岩器昵称为烟灰缸的用户离开聊天室总结(收获与体会)附:源代码注:以下代码包括了一点VC自
9、动帮我们生成的部分。客户端源代码:CMyChatApp 类中的 Initlnstance 方法:BOOL CMyChatApp: : Initlnstance ()初始化实例。if (!AfxSocketInit()初始化 WINSOCK 环境,一旦选择支持 WINSOCKET 类则 由MFC为我们自动生成。(AfxMessageBox (IDP_SOCKETS_INIT_FAILED);return FALSE;AfxEnableControlContainer();/ Standard initialization/ If you are not using these features
10、and wish to reduce the size / of your final executable, you should remove from the following / the specific initialization routines you do not need.AFXDLLEnable3dControls();#else/ Call this when using MFC in a shared DLLEnable3dControlsStatic() ;/ Call this when linking to MFC staticallyttendifCClie
11、ntSocket *clientSocket;clientSocket = new CClientSocket () ;/NEW 一个 CClientSocket 对象,用来之 后与服务器端建立连接。CLoginDlg* loginDlg;loginDlg = new CLoginDlg(clientSocket) ;NEW一个 CLoginDlg 对象。if (loginDlg-DoModal () = IDCANCEL)/显示这个登陆窗口,并判断返回值是 否来IDCANCEL,如是delete clientSocket;delete loginDlg;则 delete 这两个对象。retu
12、rn false;/返回false后程序结束。elsedelete loginDlg;如果用户点击的是登陆按钮,则会调用对应的消息处理 函数,并delete这个登陆窗口对象。CMyChatDlg *dlg;dig = new CMyChatDlg(clientSocket);m_pMainWnd = dlg;/m_pMainWnd 是 CWinThread (是 CMyApp 的基类)的一个成 员变量,用于储存一个指向我们创建的一个线程的主窗口的对象。int nResponse = dig-DoModal ();显示客户端主窗口,并接受函数的返回值。 return FALSE;)在CMyCha
13、tApp类中的成员变量:CString mstrName;定义了一个结构体: typedef struct tagHeader (chartype;intlen; Header, *pHeader;ftdefine L0GIN_I01ttdefine SEND_MESSAGE3客户端套接字类中的OnReceive成员函数:void CClientSocket:OnReceive(int nErrorCode) (/ TODO: Add your specialized code here and/or call the base class char buffsizeof(Header);me
14、mset(buff, 0, sizeof(buff);Receive (buff, sizeof(buff);Header header = (Header*)buff;这里需要一个类型的转换。int length = header-len;char type = header-type;if (type = SEND_MESSAGE) (chatDlg-GetMessage ();定义一个 CMyChatDlg *类型的 chatDlg 变量作用哈尔滨工业大学(威海)计算机学院VC+课程设计验收及成绩评定表(项目组)班号1004104项目名称聊天室程序设计职责学号姓名主要分工组长100410
15、424服务器端成员100410407客户端成员100410409服务器端成员100410421客户端指导教师设计地点设计开始日期项目完成日期文档评审成绩(共35分)评审项目评审内容成绩标准评审成绩文档格式文档格式是否规范;文字是否规范; 图表是否规范;术语是否准确10分文档质量程序设计思想与整体框架是否清晰20分文档一致性文档与程序是否一致5分文档总体评价总成绩界面友好和美观性评价(共10分)评审项目评审内容成绩标准评审成绩实现方法图形界面或命令行界面,美观程度5分实现语言面向过程或面向对象5分界面总体评价总成绩程序功能完备性评审成绩(共40分)评审项目评审内容成绩标准评审成绩程序运行状况程序
16、是否能正常运行;是否出现死 锁;是否遇到错误而中止运行10分程序正确性对于给定的输入数据,是否能得到正 确的输出结果15分程序与文档的一致性程序与各种文档的内容是否一致5分程序的代码量程序代码量的大小10分程序总体评价总成绩就在此体现。)if (type = LOGIN。)收到服务器告知的更新用户的消息、。chatDlg-UpdateUser(); 调用 CMyChatDlg 类中的 UpdateUser 方法。CSocket:OnReceive (nErrorCode);)在这个类中还定义了两个公有的成员变量:CMyChatDlg *chatDlg; 用来调用主窗口 中的 GetMessag
17、e 和 UpdateUser 方法。CString n)_strName;存放该客户端的昵称。登陆窗口类的构造函数:CLoginDlg: :CLoginDlg(CClientSocket *p Socket, CWnd* pParent /*=NULL*/) 创 建它的对象的时候需要传递它一个CClientSocket对象:CDialog (CLoginDlg: : IDD, pParent) 的地址,用来建立连接。ASSERT(p_Socket);断言assert是一个宏,一般可以用在判断某件操作是否成 功上。mpSocket = p_Socket; 提取传递进来的参数。/ AFX_DATA
18、_INIT(CLoginDlg)mstrName = _T();m_strServer = _T(127. 0. 0. 1) ;_T是一个宏,这里的作用相当于初始化了这 两个控件的值。/)AFX_DATA_INIT)登陆窗口的确定按钮响应函数:void CLoginDlg:0n0K()(/ TODO: Add extra validation hereUpdateData();用来刷新数据的,如果参数为真,则刷新控件的值到对应的变 量,若为假,则方向相反。/ m_pSocket-m_strName = this-m_strName;if (! m_pSocket-Create () 创建。Af
19、xMessageBox(网络创建错误! ! ! ); m_pSocket-Close();return;)if (!m_pSocket-Connect (m_strServer, 9999)连接,参数分别为服务器 IP 和 端口号。(AfxMessageBox (连接服务器失败!); m_pSocket-Close();return;)Header head;head, type = LOGIN IO;head, len = m strName. GetLengthO ;m pSocket-Send(char *)&head, sizeof (Header);向服务器端发送预备消 息,告知消息
20、类型,准备好接受数据。m_pSocket-Send (m_strName, m_strName. GetLength (); 发送该客户端 的用户 昵称。theApp. m_strName = m_strNanie;如果不加此行,用户的昵称将无法显示到聊 天窗口CDialog:OnOK();调用基类的ONOK函数,MFC自动调用的。)登陆窗口类中的成员变量有:CClientSocket *m_pSocket;CString m_strName;CString m_strServer;重载了一个CMyChatDlg类的构造函数:CMyChatDlg:CMyChatDlg(CC1ientSocke
21、t *p_Socket, CWnd* pParent /*=NULL*/) 需要传递已经和服务器建立连接的CClientSocket对象:CDialog(CMyChatDlg: : IDD, pParent)CClientSocket 始终是一个主线,整个 流程都要用到它,因此必需传递它。(mpSocket = p_Socket; 提取传递的参数。m_pSocket-chatDlg = this;将本窗口的对象地址赋值给m_pSocket中的成员变量 chatDlgo/AFX_DATA_INIT (CMyChatDlg)m_strMessage = _T ();/初始化控件值。m num =
22、_T();/AFX_DATA_INIT/ Note that Loadicon does not require a subsequent Destroylcon in Win32 m_hlcon = AfxGetApp。-LoadIcon(IDR_MAINFRAME); 读取图标。)DoDataExchange函数,完成了控件与变量的关联(前几个类中也有该函数): void CMyChatDlg:DoDataExchange(CDataExchange* pDX) (CDialog:DoDataExchange(pDX);/ AFX_DATA_MAP(CMyChatDlg)DDX_Contr
23、ol(pDX, IDC_LIST_USER, m_UserList);DDX Control (pDX, IDC EDIT LIST, m MessageList);DDX Text (pDX, IDC_EDIT MESSAGE, m strMessage);DDX_Text (pDX, IDC_STATIC_NUM, m_num);/AFX_DATA_MAP )消息映射宏:EGIN_MESSAGE_MAP(CMyChatDlg, CDialog)/AFX_MSG_MAP(CMyChatDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON
24、()ON_BN_CLICKED(ID_SEND, OnSend)/AFX_MSG_MAPEND_MESSAGE_MAP()CMyChatDlg 类中的 OnSend 方法:void CMyChatDlg: :OnSend() 响应发送按钮的函数。 (UpdateDataO ; 控件的值一变量if(m_strMessage = ) AfxMessageBox(不能发送空消息! ! ! );CEdit *pEdit = (CEdit*)GetDlgItem(IDC_EDIT_MESSAGE) ;/得到该控件类 型的对象地址。pEdit-SetFocus();调用成员函数设置焦点。return;He
25、ader head;head, type = SEND_MESSAGE;head, len = m_strMessage. GetLengthO ;CTime time = CTime: :GetCurrentTime();得到系统当前时间。CString t = time. Format (%H:%M:%S);设置时间格式。CString nikeName = theApp. m_strName;CString str =nikeName+ + t + rn +m_strMessage;把要发送的信息都存储在这str变量中。m_pSocket-Send(char *)&head, sizeo
26、f (Header);发送“头信息”。/ TODO: Add your control notification handler code hereif (m pSocket-Send (LPCTSTR) str, str. GetLength () 发送用户编辑的信 息,并判断Send函数的返回值。m_strMessage = ;UpdateData (FALSE); 变量一控件的值CEdit *pEdit =(CEdit*)GetDlgltem(IDC_EDIT_MESSAGE);pEdit-SetFocus();)elseAfxMessageBox(网络传输错误!”);)CMyChatD
27、lg 类中的 OnCancel 方法:void CMyChatDlg: :OnCancel ()/响应退出键。(/ TODO: Add extra cleanup hereif (m_pSocket)m_pSocket-Close();关闭连接。delete m_pSocket;)CDialog:OnCancel();CMyChatDlg 类中的 GetMessage 方法:BOOL CMyChatDlg:GetMessage()由 CClientSocket 对象中的 OnReceive 方法调用。 (char buff 1000;定义一个数组来接受消息。memset (buff, 0, s
28、izeof (buff); 将数组全部初始化为 0。m_pSocket-Receive (buff, sizeof (buff), 0) ;/接受消息。CString strTemp = buff;strTemp += _T(rn);m_MessageList. ReplaceSel (strTemp);用 strTemp变量中的内容替换消息显示 框控件的当前区域。return TRUE;CMyChatDlg 类中的 UpdateUser 方法:oid CMyChatDlg:UpdateUser()(char buff1000;memset(buff, 0, sizeof(buff);m_pS
29、ocket-Receive(buff, sizeof (buff), 0);CString user_info = buff;CString array100;存放用户名称int b = 0;for( int i=0; iuser_info. GetLengthO ; i+ )拆分服务器端发来的用户名 称,并用ARRAY数组来存储。if (i != (user_info. GetLengthO - 1)/判断是否已经到达 UER INFO 的 尾端。if ( user_infoi=&)判断是否已经到一个昵称的结尾。(b +; 用户加一) else (arrayb = arrayb + user
30、_infoi;将一个用户名称拷贝到一个数组单元中。m_num. Format (%d,b+1);将 INT 类型的 b 转换为 CString 类型。UpdateData (FALSE); 变量到控件。m_UserList. ResetContent (); 置空列表框。for (int j=0; j系统的设计与分析第一个函数:void CLoginDlg:OnOK() 登陆窗口的登陆按钮响应函数。(UpdateData。;/用来刷新数据的,如果参数为真,则刷新控件的值到对应的变量, 若为假,则方向相反。/ m_pSocket-m_strName = this-m_strName;if(! m
31、_pSocket-Create() 创建。AfxMessageBox(网络创建错误! ”);m_pSocket-Close();return;if(!m_pSocket-Connect(m_strServer,9999)/连接,参数分别为服务器 IP 和端 口 号。(AfxMessageBox(连才妾服务器失贝攵! ”);m_pSocket-Close();return;)Header head;head.type = LOGIN_IO;head.len = m_strName.GetLength();m_pSocket-Send(char *)&head,sizeof(Header);向服务
32、器端发送预备消息,告知 消息类型,准备好接受数据。m_pSocket-Send(m_strName,m_strName.GetLength();/ 发送该客户端的用户昵 称。theApp.m_strName = m_strName;如果不加此行,用户的昵称将无法显示到聊天 窗口CDialog:OnOK();调用基类的ONOK函数,MFC自动调用的。)第二个函数:void CClientSocket:OnReceive(int nErrorCode) /处理服务器端发送的消息(char buffsizeof(Header);memset(buff,0,sizeof(buff);Receive(buff,sizeof(buff);Header * header = (Header*)buff; 这里需要一个类型的转换。int length = header-len;char type = header-type;if(type = SEND.MESSAGE)