用VC++简单的多线程聊天室程序完整课程设计_第1页
用VC++简单的多线程聊天室程序完整课程设计_第2页
用VC++简单的多线程聊天室程序完整课程设计_第3页
用VC++简单的多线程聊天室程序完整课程设计_第4页
用VC++简单的多线程聊天室程序完整课程设计_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

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

文档简介

1、课程设计书学院计算机学院专业计算机科学与技术班级题目教师学生课程设计任务书课程名称VC+课程设计 时间题目局域网聊天室程序主要内容:该系统要求完成聊天室的全过程,包括客户端和服务器两大部分的 编程及其连接。服务器端聊天程序负责接收和发送来自客户端的聊天信 息,客户端聊天程序负责建立和维护与服务器端的连接,想服务器发送 本客户的聊天内容。系统米用 VISUAL C+语言程序设计编程实现。要求:(1)通过实际软件项目的分析、设计、编码、测试等工作,掌握用 软件工程的方法来开发和维护软件。(2) 按要求编写课程设计报告书,能正确编写分析、设计、编码、 测试等技术文档和用户使用手册。(3) 进行系统的

2、联合调试,编写系统使用说明。(4) 完成系统的文档、设计说明工作任务分配:计科098班:XX主要负责程序框架设计和服务端代码编写计科098班:XX主要负责客服端代码编写计科096班:XX主要负责软件测试及调试目录摘 要 31 引 言 41.1 课题背景及意义 41.2 实验平台介绍 41.3 可行性分析 42 需求分析 62.1 设计目的 62.2 设计要求 62.3 功能要求 62.4 系统主要功能和主要功能描述 63 设计流程图 84 调试分析过程描述 105 核心代码 175.1 服务端 175.2 客服端 226 设计的总结和体会 257 参考文献 25第17页局域网聊天室程序计算机网

3、络技术发展至今已经大大超越了人们当初的预想,无论是人们日常的工作 还是学习,我们都越来越多的依靠到互联网。各种实时性的聊天娱乐软件也同时诞生, 而且为我们的即时通讯带来了众多的方便,比如说大家所熟知的腾讯 QQ、微软的MSN、移动的Fetion等,都是做的比较成功的实时聊天工具。随着网络的日益普及,各种聊天 工具也层出不穷,但当我们学习了windows程序设计这门课程之后,我们决定设计 一个简单的聊天系统来巩固我们的学习。接下来的课程设计就是针对一个简单的网络聊 天程序,利用MFC为开发工具,实现基本的通讯功能。在课程设计中,系统开发平台 为Windows XP,程序设计设计语言采用 Visu

4、al C+,数据库采用Access程序运行平 台为 Windows 98/2000/XP。关键词 聊天软件;局域网;MFC Visual C+ ;多线程1.1课题背景及意义当今世界正处于信息时代,计算机和通信网络是这一时代所谓“信息基础设施”。在互联网相当普及的今天,在互联网上聊天对很多“网虫”来说已经是家常便饭了。聊 天室程序可以说是网上最简单的多点通信程序。一个简单的聊天室,从程序员的观点来 看就是在多个I/O端点之间实现多对多的通信。基于 SOCKE的局域网通信是一种灵活 的、易于实现的、低成本的方法。它可以运行在各种使用TCP/IP协议作为通讯协议的网络上。而在SOCKEAPI的帮助下

5、,开发基于SOCKE的局域网通信软件也是易于实现 的。1.2实验平台介绍Visual C+(简称VC)是Microsoft公司推出的目前使用极为广泛的基于 Windows平 台的C+可视化开发环境。VC基于C, C+语言,主要由是MFC组成,是与系统联系非常 紧密的编程工具,它兼有高级,和低级语言的双重性,功能强大,灵活,执行效率高, 几乎可说VC在 Windows平台无所不能。VC主要是针对 Windows系统,适合一些系统 级 的开发,可以方便实现一些底层的调用。在VC里边嵌入汇编语言很简单。当对系统性能要求很高的时候,可用 VC开发。VC在多线程、网络通信、分布应用方面,有 着不可比拟的

6、优势。1.3可行性分析本课程设计主要解决在客户端于客户端的信息交换和客户端于服务器的信息交换 及服务器的信息处理上的管理的课程设计。此程序主要分为两部分:服务器端和客户端。服务器端用于提供一个网络端口,等 待客户端发出请求,登录到此服务端,然后进行网络通讯和消息的转发;客户端可通过 服务器端的IP地址发送连接请求,然后登陆聊天室。在服务器端的成员列表栏中会显 示在线的所有人名单,有人退出聊天室,成员列表会自动除名。服务器端同时也提供了 成员之间的私聊功能,此时服务器端作为一个转发站,进行消息的转发。整个程序的主 体使用了 CSocket类的方法,实现了网络通讯聊天。先启动服务器端聊天程序,这是

7、聊天服务器需要指定一个端口号,客户端则根据这 个端口号以及服务器的网络地址与服务器进行通信。在这里,把端口号成为“聊天频 道 。在后面的程序代码分析中将看到,端口号并不等同于聊天频道,而是在聊天频道上 增加一个固定的偏移值,使得这个聊天频道不会和系统保留的端口发生冲突。服务器启动后将在这个指定的端口号中等待客户的连接。对于公共聊天室,服务 器对客户的数目不做任何限制。而对于私人聊天室,每个聊天频道则只能允许两个客户 互相连接,使得一方发送的信息只能到达对方的主机中。这里的服务器提供的是公共聊 天服务。通过分析发现,该程序完全可以通过 Visual C+中MFC完成。2需求分析2.1设计目的综合

8、运用本课程及计算机网络的相关知识设计并实现一个网络应用程序,以VisualC+乍为开发平台,通过实践复习巩固课堂所学的理论知识,提高对所学知识的综合应 用能力。2.2设计要求采用客户/服务器模式,分为客户端程序和服务器端程序。服务器采用WINSOCK I/O模型中的任一种,支持多个客户同时在线聊天。客户端程序和服务器程序通过网络交换 聊天字符串内容,服务器窗口的列表框中显示当前在线用户, 支持客户端之间的私聊(可 以通过服务器中转,或考虑 UDP丁洞直接建立端端连接)。课程设计要求设计并编程完成两个方面的内容:首先建立一个使用TCP协议的聊天 室服务器,这个服务器可以同时支持多个用户的在线聊天

9、;其次设计一个可以和服务器 通信的聊天室客户端。2.3功能要求支持多个客户端的连接,在服务器和多个客户端之间进行数据传输;接收客户端发送的消息,并显示在一个列表框中;在用户连接上后有提示,显示出连接的用户名字;发送信息时可以显示聊天的所有记录;2.4系统主要功能和主要功能描述服务器端聊天程序必须能够做3件事情:(1) 服务器聊天程序要在待定的端口上等待来自聊天客户的连接请求,并且需要维护 一个客户连接表,以记录所有成功的连接。(2) 服务器聊天程序要及时接受从各个聊天客户发送过来的信息,然后把这些信息转 发到一个或多个客户连接。对于公共聊天室,服务器将把接受到的信息向除源端 外的所有客户发送过

10、去。(3)服务器还要监控这些连接的状态,在客户主动离开或发生故障时从列表中删除相 应的表项,并及时更新连接表。客户端聊天程序需要完成以下几个功能:(1)客户端聊天程序要负责建立和维护与服务器的连接,通过获取用户的设置尝试 与服务器的连接,并且随时检测连接的状态。(2)客户端聊天程序要把用户输入的信息及时发送到聊天服务器。一般情况下,当 用户输入一行信息并且按下回车键后聊天程序就要把这一行信息发送出去,才 能及时地满足用户的交互需求。(3)要随时准备好接受来自服务器的信息,随时把接受到的信息显示出来,让用户 及时看到对方的响应。(4)在用户退出聊天过程是要关闭与服务器的连接。比较好的做法是提前通

11、知服务 器或者直接给服务器发送一条退出通知,使得服务器能够及时掌握客户端的连 接状态,把对方客户的退出信息及时发送到对等实体上。3设计流程图根据对用户的要求及功能设置可以得到以下的流程图3.1,用户首先启动客户端,登陆服务器并向服务器发送信息,启动服务器,服务器等待客户要求并向客户反馈在 线用户信息,用户向服务器发送信息,服务器处理用户的数据,然后用户开始聊天。客户端的聊天分为对所有人的信息和私聊的信息,该信息应通过程序控制分别进行处Fi靑事和哦施JtH霍才常1匚I花足勒*JT-4nbl LlAmfiX5Irnorit *trit it 务1KftM-.loairiib-1 !1_BK_1 *

12、制用户*HE1Send;i? 图3.1设计流程图4调试分析过程描述在聊天客服端启动的时候对端口进行监听,会出现图4.1的界面图4.1登陆服务器界面在客户端启动的时候,会出现图4.2的界面,该界面为客户端的连接界面图4.2登陆客户端界面(客服端1)图4.2登陆客户端界面(客服端2)图4.3为用户张三和李四连接服务器时的界面图4.3张三登陆服务器图4.3李四登陆服务器图4.4为用户李四发送消息的服务器界面rX图4.4李四发送消息服务端界面图4.5为用户张三发送消息的服务器界面图4.4张三发送消息服务端界面图4.6为用户李四发送消息的客服端界面期号:f?OMJ正雖同尸1X豈 円凹一_图4.6李四发送

13、消息的客服端界面图4.7为用户张三发送消息的客服端界面甲卑馴牺I : |倚,Q c . | 輛二号:1000岳巳g:或二烹科;初補or天臂:1W贬:在皱用戸: isn图4.7张三发送消息的客服端界面5核心代码5.1服务端(1) .启动监听UpdateData(TRUE);更新数据到类成员GetDlgltem(IDC_BTNSTART)-E nableWi ndow(FALSE); GetDlgltem(IDC_BTNSEND)-E nableWi ndow(TRUE); g_ServerSocket=socket(AF_INET,SOCK_STREAM,0);创建套接字if( INVALID_

14、SOCKET = g_ServerSocket)MessageBox(创建套接字失败!”);return ;SOCKADDR_IN svraddrsock;svraddrsock.sin_addr.S_ un .S_addr=hto nl(INADDR_ANY); svraddrsock.sin_family=AFN ET;svraddrsock.s in _port=ht on s(m_port);if ( SOCKET_ERROR =bi nd(g_ServerSocket,(SOCKADDR*)&svraddrsock, sizeof(SOCKADDR) MessageBox(套接字绑定

15、失败!”);return ;liste n(g_ServerSocket,10);监听套接字/创建接收线程 m_hAcceptthread=CreateThread(NULL,O,AcceptThread,NULL,O,NULL);if (m_hAcceptthread =NULL)MessageBox(创建接收连接线程失败!”);return ; g_hmutex=CreateMutex(NULL,FALSE,NULL);创建互斥量(2) .监听请求连接线程/接收连接DWORD WINAPI AcceptThread( LPVOID lpParameter)第仃页SOCKADDR_IN se

16、rveraddr;int addrle n=sizeof(SOCKADDR);SOCKET RecvSocket;/recv 后返回的套接字RecvSocket=accept(g_ServerSocket,(SOCKADDR *)& serveraddr,&addrle n);g_Clie ntSocket = RecvSocket;if ( INVALID_SOCKET=RecvSocket)AfxMessageBox(接受连接失败!”);return FALSE;BOOL Co ntin ueFlag=TRUE;while (Co ntin ueFlag &TRUE)g_Mutex. Lo

17、ck();BYTE recvBuffRECV_DATA_SIZE + 2=0;int recvle ngth=sizeof(recvBuff);int recvedSize = 0;recvedSize = recv(RecvSocket,(char*)recvBuff,recvle ngth,O);if(SOCKET_ERROR = recvedSize)int x=WSAGetLastError();CStri ng str;/WSANOTINITIALISEDstr.Format(” 错误代码:%d, x);AfxMessageBox(str);break ;CStri ngArray

18、RecvData;UINT CmdFlag;CChatRoomServerDlg:Split(char*)recvBuff,T,RecvData);/ 将收到的数据进行分离if (RecvData.GetSize()GetMai nWnd();/解析客服端发来的消息以便确定消息的类型switch(CmdFlag)case CONNECT:用户发来的连接请求/对用户发来的用户名和密码进行判断strTemp = CStri ng(RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLe ngth(); ZeroMemory(se ndBuff,1024

19、);将JOIN命令和用户名填入缓冲区spri ntf(se ndBuff,5|%s|,RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLe ngth();for( i=0;iUserSocket;if (RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength() !=Useri.UserName)if(SOCKET_ERROR =se nd(Useri.UserSocket,se ndBuff,strle n(se ndBuff),0)AfxMessageBox(co nnect中向各用户

20、发送消息失败!”);break;/向该用户发送一条LIST消息使其将所有在线用户加入用户列表ZeroMemory(se ndBuff,1024);strTemp=3|;for(i=0;i0)if(SOCKET_ERROR =se nd(RecvSocket,se ndBuff,strle n(se ndBuff),0)AfxMessageBox(connect 中发送 List数据失败!”);break ;将该用户加入用户列表for(i=0;iAddToUserList( RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLe ngth();入用

21、户列表strTemp=RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLe ngth(); iotime=CTime:GetCurre ntTime();strTemp仁iotime.Format(” 于:%Y 年%m月 %d 日 %H:%M:%S 登录); strTemp+=strTemp1;strTemp仁服务器;ServerDlg-SetChatRecord(strTemp1,strTemp); break;case CHAT:/群聊ZeroMemory(se ndBuff,1024);向所有其他在线的用户转发收到的消息spri ntf(

22、se ndBuff,2|%s|%s|, RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLe ngth(), RecvData.GetAt (2) .GetBuffer(RecvData.GetAt (2).GetLe ngth();for( i=0;iSetChatRecord(RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLe ngth(), RecvData.GetAt (2).GetBuffer(RecvData.GetAt (2) .GetLe ngth(); break;case

23、EXIT:for(i=0;icount;i+)/删除用户在 UserList 中的信息if(RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLe ngth()= Useri.UserName)/UserList.RemoveAt(i);for(j=i;jDeleteFromUserList(strTemp);将用户从服务器用户列表”中删除 iotime=CTime:GetCurre ntTime();strTemp仁iotime.Format(” 于:%Y 年%m月 %d 日 H:%M:%S 下线); strTemp+=strTemp1;str

24、Temp仁服务器;ServerDlg-SetChatRecord(strTemp1,strTemp);/向其他用户发送QUit消息ZeroMemory(se ndBuff,1024)spri ntf(se ndBuff,6|%s|,RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLe ngth();for( i=0;iSetChatRecord(strTemp1,strTemp); break;RecvData.RemoveAII();g_Mutex.U nl ock();Sleep(10);return TRUE;5.2客服端(1) .建立连

25、接UpdateData(TRUE);if (m_user name .I sEmpty()|m_pwd .I sEmpty()MessageBox(用户名或密码不能为空!”);return ;g_Clie ntSocket=socket(AF_INET,SOCK_STREAM,0);/ 创建套接字if( INVALID_SOCKET = g_Clie ntSocket)MessageBox(创建套接字失败!”);return ;DWORD dwIP;(CIPAddressCtrl *)GetDlgltem(IDC_IPADDRESS1)-GetAddress(dwlP);SOCKADDR_IN

26、 clie ntaddr;clie ntaddr.sin_family=AF_INET;clie ntaddr.s in _port=ht on s(m_port);clie ntaddr.sin_addr.S_ un .S_addr=hto nl(dwlP);if ( SOCKET_ERROR =conn ect(g_Clie ntSocket,(SOCKADDR *)& clie ntaddr,sizeof(SOCKADDR)MessageBox(连接服务器失败!”);return ;char sen dBuff1024=0;spri ntf(se ndBuff,1|%s|%s|,m_us

27、ername.GetBuffer(m_username.GetLe ngth(),m_pwd.GetBuffer(m_ pwd.GetLe ngth();int sen die ngth=strle n(sen dBuff);if ( SOCKET_ERROR = se nd(g_Clie ntSocket,se ndBuff,se ndle ngth,O) / 连接成功后将用户名和密 码发给服务器MessageBox(发送连接请求数据失败!);return ;hRecvThread=CreateThread(NULL,O,RecvThread,NULL,O,NULL);创建客户端接收数据线程

28、GetDlgltem(IDC_BTNSEND)-E nableWi ndow(TRUE);GetDlgltem(IDC_USERLOAD)-E nableWi ndow(FALSE);(2) 接受数据线程DWORD WINAPI RecvThread(LPVOID lpParameter)while (TRUE)g_Mutex. Lock();BYTE recvBuffRECV_DATA_SIZE + 2=0;intbuffle ngth=sizeof(recvBuff);int recvedSize = 0;Sleep(100);recvedSize = recv(g_Clie ntSock

29、et,(char*)recvBuff,buffle ngth,0);if ( SOCKET_ERROR = recvedSize)AfxMessageBox(接收数据失败!”);break ;CStri ngArray RecvData;CChatRoomClientDlg:Split(char*)recvBuff,|,RecvData); /此函数不会分解 AUDIO 命令,直接交个case处理if (RecvData.GetSize()GetMai nWnd();switch( CmdFlag)case OK:strTemp=RecvData.GetAt(1).GetBuffer(Recv

30、Data.GetAt(1).GetLe ngth(); strRecord=登陆成功;Clie ntDlg-SetChatRecord(strTemp,strRecord); break;case CHAT:群聊strTemp=RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLe ngth(); strRecord=RecvData.GetAt (2) .GetBuffer(RecvData.GetAt (2) .GetLe ngth(); Clie ntDlg-SetChatRecord(strTemp,strRecord);breakcas

31、e LIST:for(i=1;iAddToUserList(strTemp);break;case PRIVATE: strTemp=RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLe ngth(); strTemp+=悄悄地对你;strRecord=RecvData.GetAt (2) .GetBuffer(RecvData.GetAt (2) .GetLe ngth(); Clie ntDlg-SetChatRecord(strTemp,strRecord);break;case JOIN : strTemp=RecvData.GetAt

32、(1).GetBuffer(RecvData.GetAt(1).GetLe ngth(); Clie ntDlg-AddToUserList(strTemp);break;case QUIT: strTemp=RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLe ngth(); Clie ntDlg-DeleteFromUserList(strTemp);break;default:strTemp=服务器;strRecord=无法识别的指令;Clie ntDlg-SetChatRecord(strTemp,strRecord);if (g_Clie

温馨提示

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

评论

0/150

提交评论