中南民族大学软件课程设计报告电子信息工程学院09级电子工程专业题目:简易网络聊天系统学生:吴雪学号:09071002指导教师:王锦程2012年4月25日简易网络聊天系统摘要:计算机网络通信技术已经深入我们的生活,并给我们即使通信带来了很大的方随着网络的日益普及,各种聊天工具也层出不穷。本课程设计就是实现个简易的网络聊天程序。利用MFC为开发工具,实现基本的通信功能,以Windows为开发平台,VC6.0为开发环境,程序运行平台为WindowsXP。关键字:网络通信,MFC,SOCKET嵌套字,客户端,服务器第一章引言1.1课程设计的背景:在互联网非常普及的今天,网络聊天已经成为我们日常生活中不可缺少的一种通信工具,聊天程序也应该是一种基础的程序。一个简单的聊天程序,就是在多个I/O端点之间实现多对多的通信。基于SOCKET嵌套字的网通信是一种灵活的,易于实现的方法。在SOCKETAPI的帮助下,开发基于SOCKET的局域网通信软件是易于实现的。1.2课程设计的目的:本设计的目标是用C++语言设计一个实时聊天系统的程序。程序写完后最终生成一个客户端,它由client和server两部分组成,client和server之间的通信基于TCP协议。实现数据的收发。输入聊天室使用的昵称及目的主机的IP,连接到目的主机,客户端与客户端之间即可实现简易的聊天和传输文件的功能.第二章设计依据及框图2.1设计平台:本课程设计的基本的网络编程都是建立在Winsock基础上的。Winsock是90年代初,为了方便网络编程,由Microsoft联合了其他几家公司共同制定的一套WINDOWS下的网络编程接口,它是通过C语言的动态链接库方式提供给用户及软件开发者的,主要由winsock.h头文件和动态链接库winsock.dll组成,目前有两个版本:Winsock1.1和Winsock2.0。作为网络编程接口,Winsock屏蔽了网络底层的复杂的协议和数据结构,使得编程人员对网络的操作变得非常简单,因此,在Win32平台上,访问众多的基层网络协议,Winsock是首选接口。开发平台我选用了VC6.0,因为一直以来都使用VC6进行学习,对这个IDE最为熟悉,再者VC同样是由微软开发的系统,与其操作系统,网络接口具有最为密切的契合优点,所以选择了VC6.0。2.2设计思想、设计框图及数据库表结构(1)系统总体设计思想:通常的通信工具,都采用客户机/服务器(C/S)体系结构,C/S结构是这样的一种结构:它包括一个客户机(或前端),一个服务器(或称后端),客户机的作用是访问和处理远程服务器上的数据,服务器的作用是接收和处理客户机的数据请求。有时,可能有多个客户向同一个服务器同时请求服务,这就需要服务器决定怎样处理这些请求。Client/Server结构是当前数据库应用程序中极为流行的一种方式。尤其是网络技术的发展,使得当前很多系统都采用这种方式进行构造,其最大的优点是将计算机工作任务分别由客户端和服务器端来共同完成,这样有利于充分合理的利用系统资源。另外它的服务器端还可以将信息集中起来,任何客户机都可以通过访问服务器而获得所需的信息。Client/Server模型最终可归结为一种“请求/应答”关系。一个请求总是首先被客户发出,然后服务器总是被动地接收请求,返回客户需要的结果。在客户发出一个请求之前,服务进程一直处于休眠状态。一个客户提出请求后,服务进程被“唤醒”并且为客户提供服务,对客户的请求做出所需要的应答。在客户端启动后,客户端计算得到本地网络的广播地址,进行广播查找服务器端,服务器接收到客户端的广播信息后返回服务器地址,则客户端接收、验证信息并记录服务器端地址,然后客户端启动定时期,定时发送信息到服务器,以告知服务器自己在线,然后服务器返回在线用户列表,服务器依靠客户端发送的信息来更新维护在线用户列表。在客户端与服务器尽心数据交换,拥有了在线用户列表后,就可以选择IP进行客户端之间的点对点信息交流了。如果服务器不在线,则客户端会提示用户退出,在一定的时间后自动退出。(2)设计框图图(1)设计思路框图(3)数据库表结构及表间关系图(2)数据库表结构及表间关系第三章各模块功能及主要模块的流程图3.1各模块功能简介1.Connect():intconnect(SOCKETs,conststructsockaddrFAR*name,intnamelen);【使用说明】与通信对象建立连接,主要用在客户端。其中s、name和namelen的含义与使用方法和bind()相同。如果连接失败,该函数会返回SOCKET_ERROR。2.listen():intlisten(SOCKETs,intbacklog);【使用说明】对于服务器端程序,当申请到Socket,并指定通信对象为INADDR_ANY之后,就应该等待一个客户端程序的连接。当没有连接请求时,就进入等待状态,直至有一个请求到达为止。其中:s输入:是socket()创建的socket。backlog输入:等待连接的队列长度,可取1~5。如果当某个客户程序要求连接之时,服务器已与其他客户程序连接,则后来的连接请求会被放在队列中,等待服务器空闲的时候再与之连接。当队列达到指定长度(backlog的值)时,再来的连接请求都将被拒绝。聊天室服务器端客户端界面接收入接收发送监听器结束接口接口输入输出输入输出发送3.accept():SOCKETaccept(SOCKETs,structsockaddrFAR*addr,intFAR*addrlen);【使用说明】对与服务器端程序,在接收到一个连接请求之后,要为这个连接建立一个新的socket,这个任务由accept()函数来完成,并把它作为返回值。新建的Socket与原来的Socket有相同的特性,包括端口号。原来的Socket用于继续等待其他的连接请求,而新生成的Socket才是与客户端进行通信的实际Socket。一般将参数中的SOCKET称做“监听”Socket,它只负责接受连接,不负责通话;而accept返回的SOCKET则称为“会话”Socket,它只负责与客户端通话。参数中的指针addr和addrlen用来返回客户机的sockaddr_in结构体,通过addr可得到客户机的IP地址和连接端口。使用方法则与bind()中的name和namelen相同。4.recv()/send():建立连接后,用来接收和发送数据。其中:s输入:是连接用的socket。buf、len和flags的含义与作用方法与recvfrom()/connect()中的相同,分别表示接收和发送的数据包字符串的地址、长度和标志。3.2主要流程图(四号宋体加粗)图(3)分别为服务器端和客户端流程图第四章软件调试分析图(4)服务器端显示界面图(5)客户端显示界面图(6)几个同学聊天记录客户端显示图(7)聊天时的服务器端第五章结语5.1结论与讨论:用C语言编写Windows应用程序有两种方式:一种是WindowsC编程方式,另一种是VisualC++编程方式。在一般情况下,VisualC++编程方式编写的程序源代码量小、开发时的工作量小、工作难度也较小,但编译后的代码量较大,运行速度略低;而WindowsC编程方式编写的程序源代码量虽然较大,但可执行代码效率高。随着技术的进步,VisualC++编程方式已被广泛采用,但象网络编程等一些对速度要求高、对硬件操作较多的程序,大多数还是用WindowsC编程方式开发的。在上面的程序中,大家注意到,客户端程序,我并没有把要发送的信息直接显示在ID编辑框中,而是在发送后,由服务器端再发给各个进入聊天室的客户,客户端程序连接完成,就开始接收服务器发送的信息,这样的客户端程序,事实上就是一个简单的端口扫描程序,有兴趣的读者可以试试连接不同IP地址机器的不同端口,就可以根据返回的的信息,判断这台机器都开启了哪些网络服务程序了。通过聊天室程序的编写,可以基本了解WindowsSocketsAPI编程的基本过程和精要之处。本程序在VC++6.0下编译通过,在使用windows98/2000/XP/NT的局域网里运行良好。参考文献[1]侯俊杰.深入浅出MFC[M].华中科技大学出版社.2001[2]孙鑫.VC++深入详解[M].电子工业出版社.ISBN7-121-02530-2[3]黄强.WINDOWS网络编程[M].人民邮电出版社.ISBN978-7-115-10961-3附录//ChatRoomDlg.cpp:implementationfile//#includestdafx.h#includeChatRoom.h#includeChatRoomDlg.h#ifdef_DEBUG#definenewDEBUG_NEW#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#endif///////////////////////////////////////////////////////////////////////////////CAboutDlgdialogusedforAppAboutclassCAboutDlg:publicCDialog{public:CAboutDlg();//DialogData//{{AFX_DATA(CAboutDlg)enum{IDD=IDD_ABOUTBOX};//}}AFX_DATA//ClassWizardgeneratedvirtualfunctionoverrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDVsupport//}}AFX_VIRTUAL//Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg():CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}voidCAboutDlg::DoDataExchange(CDataExchange*pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)//{{AFX_MSG_MAP(CAboutDlg)//Nomessagehandlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////////CChatRoomDlgdialogCChatRoomDlg::CChatRoomDlg(CClientSocket*tmp,CWnd*pParent/*=NULL*/):CDialog(CChatRoomDlg::IDD,pParent){//{{AFX_DATA_INIT(CChatRoomDlg)m_IDC_EDIT_MESSAGE=_T();m_IDC_EDIT_ADDRESS=_T(127.0.0.1);m_IDC_EDIT_NIKENAME=_T();m_SL=FALSE;//}}AFX_DATA_INIT//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32m_hIcon=AfxGetApp()-LoadIcon(IDR_MAINFRAME);myServerSocket=tmp;}voidCChatRoomDlg::DoDataExc