网络编程_基于TCP的简易聊天室_实验报告

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

网络编程课程设计说明书题目名称:基于TCP/IP的网络文字聊天程序设计专业:网络工程班级:1201班学号:1220140105姓名:蒋星指导老师:陈利平完成日期:2014年12月13日目录一、实验基本信息概要31.题目要求32.题目内容33.开发环境3二、流程图4三、系统简介51.界面52.软件功能53.系统设计94.优点与缺点9四、系统详细设计111.ChatServer类112.ChatClient类133.SocketException类155.命令协议156.消息格式16五、系统测试161.服务器使用错误162.客户端使用错误173.启动服务器174.启动客户端175.关闭客户端176.启动服务器错误提示187.公开聊天188.私聊189.错误的私聊1910.更名2011.帮助2012.非法指令2013.非法的指令参数2014.连接服务器失败21六、心得体会21七、完整代码21Charserverd.cpp服务器main函数文件21ChatServer.h服务器类头文件22ChatServer.cpp服务器类23ClientInfo.h客户信息类33Charclientd.cpp客户端main函数34ChatClient.h客户端头文件34ChatClient.cpp客户端类35InitSock.cpp初始化WINSOCK类41SockException.h异常类41八、[参考文献]42一、实验基本信息概要1.题目要求1、开发平台VisualC++6.0。2、对设计方法的要求使用VisualC++6.0开发出在Windows控制台或图形界面下运行的程序。3、对设计内容的要求①实现网络文字聊天程序的服务器端。②实现网络文字聊天程序的客户端。③主程序的结构和流程。④程序运行过程的截图。⑤网络文字聊天程序的实现原理。⑥网络文字聊天程序实现代码的分析。4、对课程设计说明书的要求①设计思路与开发过程。②对主要代码段要有较详细的注释。③对本次设计的评价、设计的收获与建议。5、说明书为打印件2.题目内容内容概要:实现网络文字聊天程序的基本功能。3.开发环境操作系统:Windows7开发语言:C++集成开发环境:MicrosoftVisualStudio2010二、流程图三、系统简介1.界面本软件使用DOS控制台界面,界面风格较为朴素。服务器:客户端:2.软件功能本软件实现了聊天室基本的功能,包括公开聊天,私聊,获取在线用户,更改昵称,获得帮助等。1)公开聊天在光标处直接输入消息后按回车即为发送公开聊天,如下图所示。2)私聊使用命令【/m对方UID消息】即可发送私聊,私聊只有对方可以看到,如下图所示:客户端1,密聊UID为132的用户。发送后客户端2,UID为132的用户收到私聊消息。3)获取在线用户列表使用命令【/list】即可获得在线用户列表,用户列表会议系统消息的方式返回,如下图所示。命令发送后4)更改昵称使用命令【/name你的新昵称】即可立即更改昵称,成功修改后服务器会以系统消息的方式返回成功修改的提示。命令命令发送后5)帮助信息使用命令【/help】即可查看服务器的欢迎信息,里面包含了该聊天室的使用帮助,如下图所示。命令命令发送后3.系统设计开发本软件时,我使用了面向对象的思想,把服务器和客户端封装成对应的类,类设计将会在下一节做详细介绍。通行方面我在服务器接受客户端消息,和客户端接受服务器消息时使用了select模型,发送信息我使用的是普通的socket原语。基本原理为服务器与客户端建立TCP连接,然后服务器负责路由消息到各个客户端。4.优点与缺点本软件对流程复杂的SELECT模型进行了细致的拆分与抽象,做到了逻辑流程清晰,每个函数简洁易懂,层次分明。例如服务器启动函数:voidChatServer::Start(){InitListenSocket();Bind();Listen();InitFDSocket();while(true){DoSelect();}}try{charServer.Start();}catch(SockExceptione){coute.GetErrorInfo()endl;cout[SystemError]ErrorCode:e.GetErrorCode()endl;}它其实就完成了一个简单的流程,初始化socket,绑定,监听,初始化fd_socket集合,死循环调用select。通过合理的封装底层原语和加入异常处理(异常交给顶层处理),使得代码专注于业务流程而不是繁杂的异常判断语句,在看下面这个函数DoSelect()。voidChatServer::DoSelect(){m_fdRead=m_fdSocket;intnRet=Select();if(nRet0){for(inti=0;im_fdRead.fd_count;i++){DoFDRead(m_fdRead.fd_array[i]);}}}它也只完成一个简单的流程,调用select,然后循环处理有读事件的socket。voidChatServer::DoRead(SOCKETsRead){if(sRead==m_sListen){RecvNewConnect();}else{m_sNowClient=sRead;RecvNewConnect();}}接下来的DoFDRead()函数完成的事情也非常直接,如果有事件的socket是监听socket的话,那么就是接收到了一个新的连接,否则是接收到了新的小。从上面这个简单的例子中可以看到,本软件最大的优点就是精心设计的类和函数。避免了使用select模型常见的反复嵌套的循环和判断,每个函数清晰明了。本系统还存在以下不足,首先是没有对界面做更深入的优化,只是做了最基本的调整,让输入输出更加雅观,其次是底层原语的封装并没有考虑到泛用性。四、系统详细设计这部分的文档在编码之前已经基本完成,由于时间较为仓促,部分内容可能和实际有所出入。1.ChatServer类该类负责完成服务器所有操作。1)类图2)成员变量MapSOCKET,stringm_clients聊天者的SOCKET与昵称的映射fd_setm_fdSocket可用套接字集合fd_setm_fdRead有事件发生的套接字集合SOCKETm_sListen监听SocketSOCKETm_sNowClient当前处理的客户套接字intm_nPort监听端口3)方法设计voidBind()voidListen()voidSelect()intRecv()SOCKETAccept()封装底层原语,并加入异常机制,使得外部调用简约明了。构造函数传入监听端口,初始化m_nPortStart()1)初始化监听套接字:voidInitListenSocket()2)绑定套接字至本地机器:voidBind()3)进入监听模式(设置为非阻塞):voidListen()4)初始化可用套接字集合voidInitFDSocket()5)死循环,调用select方法DoSelect()6)结束DoSelect()1)令m_fdRead=m_fdSocket2)调用Select()3)循环处理Select的结果DoFdRead(SocketsRead)4)结束DoFdRead(intiReadIndex)1)判断是否为m_sListen2)是m_sListenRecvNewConnect()3)否则令m_sNowClient=m_fdRead[iReadIndex],调用RecvNewMessage()RecvNewConnect()1)判断是否达到套接字上线2)调用Accept(),接收连接sClient3)添加sCilent至m_fdSocket4)添加套接字至m_clientsAddClientToInfoMap(stringname)AddClientToInfoMap(stringname)1)以SOKCET为键,name为值加入MAPRecvNewMessage()1)调用Recv函数2)是否为命令IsCommand(stringstr)3)是,则DoCommand(stringcmd)4)否,则DoMessage(stringmsg)5)结束IsCommand(stringstr)1)判断是否以/开头DoCommand(stringcmd)1)判断指令,并解析命令与参数(argc,argv)2)调用指令处理函数3)假设只有SetName命令,那么则将对应的套接字的名称设置DoMessage(stringmsg)1)拼接消息与名字BuildMsg(stringmsg)2)在服务器上输出3)消息路由DispatchMessage(stringmsg)BuildMsg(stringmsg)1)从m_clients中取出用户昵称2)拼接字符串,形成格式如下超人君(127.0.0.1)23:49:48说:大家好!即为:昵称(IP地址)时间说:消息正文3)返回DispatchMessage(stringmsg)1)构造迭代器2)遍历m_clients,若不是自身,则派送消息Send()2.ChatClient类该类负责处理客户端的所有操作。1)类图2)字段设计SOCKETm_sClient客户端自身的socketSOCKETm_sServer服务器socketstringm_name昵称sockaddr_inm_ServerAddr;服务器地址3)方法设计构造函数根据端口号和服务器IP初始化m_serverConnect()voidSelect()intRecv()voidSend()intSelect()封装底层原语,加入异常处理,使得外部调用节约优雅voidStart()1)初始化套接字InitClientSocket()2)连接服务器Connect()设置为非阻塞模式3)获取名字并发送至服务器InitName()4)创建新线程并显示替他用户发言线程函数RecvMsgThread()5)循环SendMsg()6)关闭客户端CloseClient()InitName()1)提示输入昵称2)获取昵称3)合法性判断判断重复4)添加命令格式5)发送至服务器SendMsg()1)读取一行消息2)判断是否为命令IsCommand(stringstr)3)命令:处理命令DoCommand(stringcmd)4)消息:处理消息DoMessage(stringmsg)DoMessage(stringmsg)1)发送消息Send()2)本地回显RecvMsgThread()1)初始化fdSocket,将m_sClient加入2)创建fdRead3)死循环,将m_sClient拷贝至fdRead4)调用Select5)循环,并输出收到的消息Recv()3.SocketException类该类负责记录SOKCET错误的代码以及错误信息。5.命令协议命令格式为/命令参数1参数21.退出:/exit2.获取在线用户列表:/getuser3.私聊:/mUID信息4.清屏:/clear5.帮助:/help处理方式IsCommand(stringstr)负责解析是否为命令判断首字母是否为斜杠/str.at(0)=='/'ResoveCommand(stringcmd,int&argc,stringargv[])若是命令将命令解析为argc,argvDoCommand(stringcmd)处理命令,调用具体的XXX命令处理函数DoCmdXXXX()。6.消息格式1)公共消息超人君(127.0.0.1)UID:100说:大家好!李四(127.0.0.1)UID:101说:你好!!2)私聊你悄悄地对ABCUID:100说:你好CDFUID:101悄悄地对你说:你好3)服务器消息【系统消息】XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。4)程序内部提示[SystemInfo]xxxxxxxxxxxxxxxxxxxxxxxxx五、系统

1 / 42
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功