基于TCP协议网上聊天程序_第1页
基于TCP协议网上聊天程序_第2页
基于TCP协议网上聊天程序_第3页
基于TCP协议网上聊天程序_第4页
基于TCP协议网上聊天程序_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

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

文档简介

1、桂林电子科学大学课程设计说明书用纸编号: 计算机网络课程设计说明书 题 目: 基于TCP协议网上 聊天程序 系 别: 专 业: 学生姓名: 学 号: 指导教师: 2013 年 3 月 27 日 目 录1 设计任务21.1 系统设计目标21.2 聊天程序的功能22 系统分析22.1系统理论基础22.2 客户机/服务器模式32.3 Sokect介绍42.4 系统开发环境52.5 系统结构设计53 总体设计53.1 体系结构设计53.2 网络通信设计63.3 模块设计8 3.31服务器8 3.32客户端94 详细设计104.1 设计服务器和客户端的界面104.2 实现服务器和客户端通过网络通信114

2、.3 实现多个客户端之间的实时聊天功能115 总结166 使用说明16参考文献20第 0 页 共 22 页1 设计任务1.1 系统设计目标 深入理解计算机网络基本原理,将书本上抽象的概念与具体的实现技术相结合,体会网络协议的设计与实现过程,以及专业技术人员所使用的基本方法和技巧。基于TCP协议网上聊天程序实现一简单的聊天程序,实现网上聊天,包括服务器和客户端。要求: (1)支持多人聊天。(2)客户端具有图形化用户界面。1.2 聊天程序的功能客户端使用简便,服务器端运行稳定。客户端与服务器端可运行在多种系统平台,具有良好的兼容性能。客户端与服务器端功能独立,可独立运行在不同的计算机上或运行在同一

3、台计算机上,具有最大的灵活性。 根据任课教师的要求及我自己的编程能力,写出以下的功能: 1、 登录时只需要提供用户名即可,无需输入密码。 2、 允许多人在线聊天。 3、 聊天发送的消息包括:用户名称、发送时间及正文。 4、 某用户刚登录服务器时,服务器需对其发送实时在线用户列表。 5、 某用户登录或退出程序时都需要给服务器发送一个消息以通知其他用户。 6、 能够查看聊天记录。 2 系统分析2.1 系统理论基础TCP/IP的特点 TCP/IP协议的核心部分是传输层协议(TCP、UDP),网络层协议(IP)和物理接口层,这三层通常是在操作系统内核中设计。因此用户一般不涉及。TCP是面向连接的,通信

4、双方保持一条通路,好比目前的电话线,使用telnet登陆BBS,用的就是TCP协议;UDP是无连接的,通信双方都不保持对方的状态,浏览器访问Internet时使用的HTTP协议就是基于UDP协议的。编程时,编程界面有两种形式:一、是由内核心直接提供的系统调用;二、使用以库函数方式提供的各种函数。前者为核内设计,后者为核外设计。用户服务要通过核外的应用程序才能设计,所以要使用套接字(socket)来设计。2.2 客户机/服务器模式 C/S结构(Client/Server结构)是大家熟知的客户机和服务器结构。它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端

5、和Server端来实现,降低了系统的通讯开销。目前大多数应用软件系统都是Client/Server形式的两层结构,由于现在的软件应用系统正在向分布式的Web应用发展,Web和Client/Server 应用都可以进行同样的业务处理,应用不同的模块共享逻辑组件;因此,内部的和外部的用户都可以访问新的和现有的应用系统,通过现有应用系统中的逻辑可以扩展出新的应用系统。这也就是目前应用系统的发展方向。 首先服务器方要启动,并根据请求提供相应服务: (1)打开一通信通道并告知本地主机,它在某一公认地址端口上(如http为80)接受客户请求。 (2)等待客户请求到达该端口。 (3)接收到重复服务请求,处理

6、该请求并发送应答信号。接收并发服务请求,要激活一新进程来处理这个客户请求。新进程处理此客户请求,并不需要对其他请求做出应答。服务完成后,关闭此新进程与客户的通信链路,并终止。 (4)返回第二步,等待另外的客户请求 (5)关闭服务器。 客户方: (1)打开一通信通道,并连接到服务器所在主机的特定端口。 (2)向服务器发出服务请求报文,等待并接收应答;继续提出请求。 (3)请求结束后关闭通信通道并终止。 从上面的描述过程可知: (1)客户与服务器进程的作用是非对称的。因此编码不同。 (2)服务进程一般是先于客户请求启动的。只要系统运行,该进程一直存在,直到正常终止或者强迫终止。 在TCP/IP网络

7、中两个进程间的相互作用的主机模式是客户机/服务器模式(Client/Server model)。该模式的建立基于以下两点:1、非对等作用;2、通信完全是异步的。客户机/服务器模式在操作过程中采取的是主动请求服务响应的方式。2.3 Socket介绍Socket是建立在传输层协议(主要是TCP和UDP)上的一种套接字规范,最初是由美国加州Berkley大学提出,它定义两台计算机间进行通信的规范(也是一种编程规范),如果说两台计算机是利用一个“通道”进行通信,那么这个“通道”的两端就是两个套接字。套接字屏蔽了底层通信软件和具体操作系统的差异,使得任何两台安装了TCP协议软件和实现了套接字规范的计算机

8、之间的通信成为可能。微软的Windows Socket规范(简称Winsock)对Berkley的套接字规范进行了扩展,利用标准的Socket的方法,可以同任何平台上的Socket进行通信;利用其扩展,可以更有效地实现在Windows平台上计算机间的通信。Socket减轻了编写计算机间通信软件的难度;标准的Socket的应用程序框架如下:Server方:Socket()新建一个SocketBind()同服务器地址绑定Listen()Accept()block waitread()接受消息,在windows平台中,方法为send(TCP),或者是send to(UDP)处理服务请求Write()

9、发送消息,在windows平台中,方法为send(TCP),或者为send to(UDP)。Client方相对简单:Socket()Connect()通过一定的port连接特定的服务器,这是与服务器建立连接Write()Read()。Socket可以是基于TCP的,也可以是基于UDP,同时Socket甚至建立在其他的协议,比如IPX/SPX,DECNet等。在新建一个Socket时,可以指定新建何类Socket。Bind()用来同服务器的地址绑定,如果一个主机只有一个IP地址,实际上绑定的作用就相对多余了。Listen()开始监听网络,Accept()用于接受连接,其返回值是保持同客户机联系的

10、Socket。在VC+ 2008中,其底层的Socket也应该是Windows的Socket。Inprise在VC+2008中对Windows Socket进行了有效的封装,使得用户可以很方便地编写网络通信程序。Socket系统调用包括创建Socket、将创建的Socket与本地端口绑定、建立Socket连接服务器、监听是否有连接、请求数据的可控缓冲发送和可控缓冲接收,到最后关闭Socket。首先在服务器方,利用socket()函数建立流式套接字,返回套接字号s,接着利用bind()函数将套接字s与本地地址绑定,紧接着利用listen()函数通知TCP,监听客户方,服务器准备接收连接,没有连接

11、的话,服务器方通过closesocket()关闭套接字s,服务结束。有连接的话,在客户方,通过socket()函数建立流式套接字s,此时在服务器方,建立连接,通过accept()返回,得到新的套接字ns,客户方通过connect()将套接字s与远程地址连接,此时服务器方/客户方在ns/s上读/写数据,直到交换完成。交换完成后,服务器方/客户方关闭套接字ns/s,最后服务器方通过closesocket()关闭最初套接字s,服务结束。2.4系统开发环境本系统开发环境采用Visual Studio 2008。编译语言采用C+。2.5系统结构设计本系统采用C/S结构,最重要的特点是非对等相互作用,即客

12、户与服务器处于不平等的地位,服务器拥有客户所不具备的硬软件资源,客户和服务器分别是服务的请求者和提供者。网络中各个机器的资源是不平等的,网络的真正目的就是共享这些不均等资源源,非对等相互作用特点也正好体现和适应了客观现实中资源的不均等现象。局域网上不同主机进程间通信完全是异步的,通信时机具有随机性,所以必须用这种为通信双方的数据交换提供同步的机制。3 总体设计3.1体系结构设计通常的通信工具,都采用客户机/服务器(C/S)体系结构,C/S结构是这样的一种结构:它包括一个客户机(或前端),一个服务器(或称后端),客户机的作用是访问和处理远程服务器上的数据,服务器的作用是接收和处理客户机的数据请求

13、。有时,可能有多个客户向同一个服务器同时请求服务,这就需要服务器决定怎样处理这些请求。Client/Server结构是当前数据库应用程序中极为流行的一种方式。尤其是网络技术的发展,使得当前很多系统都采用这种方式进行构造,其最大的优点是将计算机工作任务分别由客户端和服务器端来共同完成,这样有利于充分合理的利用系统资源。另外它的服务器端还可以将信息集中起来,任何客户机都可以通过访问服务器而获得所需的信息。Client/Server模型最终可归结为一种“请求/应答”关系。一个请求总是首先被客户发出,然后服务器总是被动地接收请求,返回客户需要的结果。在客户发出一个请求之前,服务进程一直处于休眠状态。一

14、个客户提出请求后,服务进程被“唤醒”并且为客户提供服务,对客户的请求做出所需要的应答。如下图所示: 图3.1客户机服务器通信结构示图在客户端启动后,客户端计算得到本地网络的广播地址,进行广播查找服务器端,服务器接收到客户端的广播信息后返回服务器地址,则客户端接收、验证信息并记录服务器端地址,然后客户端启动定时期,定时发送信息到服务器,以告知服务器自己在线,然后服务器返回在线用户列表,服务器依靠客户端发送的信息来更新维护在线用户列表。在客户端与服务器尽心数据交换,拥有了在线用户列表后,就可以选择IP进行客户端之间的点对点信息交流了。如果服务器不在线,则客户端会提示用户退出,在一定的时间后自动退出

15、。3.2网络通信设计在调用了Windows sockets 的启动函数WSACleanup()之后才能进行其他的Socket系统调用,但启动函数WSAStartup()是为了建立与Windows Sockets DLL的连接,因此在Visual Studio 2008所建立工程的工程设置中的连接的库模块必须进行设置,在其中的link栏内的对象/库模块中加入“Ws2_32.lib”,才能真正建立建立与Windows Sockets DLL的连接。其他的Socket系统调用包括创建Socket、将创建的Socket与本地端口绑定、建立Socket连接服务器、监听是否有连接、请求数据的可控缓冲发送和

16、可控缓冲接收,到最后关闭Socket。具体流程图如1所示。首先在服务器方,利用socket()函数建立流式套接字,返回套接字号s,接着利用bind()函数将套接字s与本地地址绑定,紧接着利用listen(0函数通知TCP,监听客户方,服务器准备接收连接,没有连接的话,服务器方通过closesocket()关闭套接字s,服务结束。有连接的话,在客户方,通过socket()函数建立流式套接字s,此时在服务器方,建立连接,通过accept()返回,得到新的套接字ns,客户方通过connect()将套接字s与远程地址连接,此时服务器方/客户方在ns/s上读/写数据,直到交换完成。交换完成后,服务器方/

17、客户方关闭套接字ns/s,最后服务器方通过closesocket()关闭最初套接字s,服务结束。具体设计过程如图3.2所示。服务器方Socket()建立流式接字,返回套接字号s客户方bind()套接字s与本地地址绑定listen()通知TCP服务器准备接收连接accept()接收连接,等待客户端的连接建立连接,accept()返回,得到新套接nsRecv()/send()在ns上读/写数据,直到完成交换closesocket(),关闭套接字nsclosesocket()关闭最初套接字s,服务结束Socket()建立流式套接字号sconnect()将套接字s与远程地址连接Recv()/send(

18、)在s上读/写数据,直到完成交换closesocket()关闭套接字s,结束TCP 图3.2 面向连接的套接字的系统调用流程图3.3 模块设计 3.31 服务器 首先运行服务器,服务器侦听端口消息,等待客户端向其建立连接的申请,一旦接收到客户端的连接请求,服务器将返回一个新的套接字描述符,通过该描述符调用数据传输函数即可与客户端进行数据的收发。服务器若接收的是登陆信息,向该用户发送在线用户列表,并更新服务器的在线用户列表;若收到的是发送信息,服务器解析信息,然后通过广播消息,向其所有线用户列表发送消息。服务器端流程图如下。 向该用户发送在线用户列表 开始侦听端口消息 解析消息向其所有在线用户发

19、送消息首次登陆更新服务器在线用户列表收到消息 运行服务器 是 否 是 广播消息 图3.31 服务器流程图 3.32 客户端 在运行服务器之后,运行客户端。客户端首先向服务器提出建立连接请求,然后建立一个套接字描述符,通过该描述符调用数据传输函数即可与服务端进行数据的收发。用户登录成功后,向服务器发送登陆消息,并更新本地在线用户列表,然后通过服务器实现与其他客户聊天;当客户退出,向服务器发送下线消息。客户端流程图如下。 开始 开始 开始 运行客户端 运行客户端 运行客户端 用户登陆 用户登陆 用户登陆给服务器发送登陆消息登陆成功登陆成功向该用户发送在线用户列表登陆成功向该用户发送在线用户列表 否

20、 是 显示主页面 显示主页面 显示主页面 是给服务器发送下线消息向其所有在线用户发送消息向其所有在线用户发送消息 是更新本地在线用户列表更新本地在线用户列表更新本地在线用户列表与其他用户进行聊天与其他用户进行聊天与其他用户进行聊天 退出 退出 退出 图3.32 客户端流程图 4 详细设计4.1 设计服务器和客户端的界面分别为客户端和服务器创建基于对话框的MFC工程。分别为其添加显示信息和输入信息的文本控件和按钮,并为其指定适当的属性。服务器和客户端的运行界面分别如图4.14.3所示。 图4.1 服务器运行界面设计 图4.2 客户端登陆界面设计 图4.3 客户端运行界面设计4.2实现服务器和客户

21、端通过网络通信服务器和客户端通过定义CSocket 类的子类来重载CSocket 类中的成员函数完成服务器与客户端之间的网络通信。服务器和客户端的交互包括客户端登录服务器,服务器将客户名添加至客户列表中,以及客户下线后,服务器和在线客户将下线客户从客户列表中删除等。4.3实现多个客户端之间的实时聊天功能 由于客户端/服务器模式,客户在进行聊天时,需要把待发送的消息发送至服务器;服务器接收到消息后,经过查询客户列表,寻找接受的客户名后,将消息转发至在线客户处。由于服务器与客户端交互时,还需接收客户端的登录信息,故将接收客户端的登录信息和接收消息发在同一个接收函数中。 根据以上步骤,对实现聊天工具

22、的服务器和客户端的关键代码解说如下。 (1)服务器初始化,开始监听客户端的连接请求,具体代码如下:BOOL CChatServerApp:InitInstance()if (!AfxSocketInit() /套接字初始化失败AfxMessageBox(IDP_SOCKETS_INIT_FAILED);return FALSE;AfxEnableControlContainer();CServerSocket *m_pSocket; /自定义的CSocket类的子类 m_pSocket = new CServerSocket;if(!m_pSocket-Create(9999) /创建套接字A

23、fxMessageBox(_T(创建Socket失败!);return FALSE;if(!m_pSocket-Listen() /监听客户端的连接请求AfxMessageBox(_T(创建侦听发生错误!);return FALSE;(2)客户端登陆至服务器,具体代码如下: void CLoginDlg:OnOK() UpdateData(); /获取文本框中数据if(!m_pSocket-Create() /创建套接字AfxMessageBox(_T(网络创建错误!);m_pSocket-Close();return;if(!m_pSocket-Connect(m_strServer,999

24、9) /连接至服务器AfxMessageBox(_T(连接服务器失败!);m_pSocket-Close();return;Header head;head.type = LOGIN_IO;head.len = m_strName.GetLength();m_pSocket-Send(char *)&head,sizeof(Header); /发送客户信息至服务器m_pSocket-Send(m_strName,m_strName.GetLength();theApp.m_strName = m_strName;CDialog:OnOK(); (3)服务器接收新登录客户的信息,具体代码如下:v

25、oid CClientSocket:OnReceive(int nErrorCode) char buff1sizeof(Header);memset(buff1, 0, sizeof(buff1);Receive(buff1,sizeof(buff1);Header *header = (Header*)buff1;int length = header-len;char type = header-type;if(type = LOGIN_IO) /如果收到的是登录信息char buff1000; memset(buff,0,sizeof(buff); Receive(buff,lengt

26、h); /接受客户登录信息CTime time = CTime:GetCurrentTime(); /获取当前系统时间 CString t = time.Format(%Y-%m-%d %H:%M:%S); /时间格式CEdit *p_Edit = (CEdit *):AfxGetMainWnd()-GetDlgItem(IDC_EDIT_INFO);CString strTemp = t + : + CString(buff) + 进入rn; /显示登录信息p_Edit-ReplaceSel(strTemp); /更新在线客户列表 m_strName = buff; m_dlgServer-

27、UpdateUser(this);if(type = SEND_MESSAGE) /如果接受的是客户发送信息char buff1000; memset(buff,0,sizeof(buff); Receive(buff,sizeof(buff); /接收消息内容CClientSocket *curr = NULL;POSITION pos = clist-GetHeadPosition();while (pos != NULL) /将消息发至在线客户curr = (CClientSocket *)clist-GetNext(pos);curr-Send(char *)header,sizeof

28、(Header);curr-Send(buff, sizeof(buff);CSocket:OnReceive(nErrorCode); (4)客户发送消息,先将消息发至服务器,具体代码如下:void CMyChatDlg:OnSend() UpdateData();if(m_strMessage = )AfxMessageBox(_T(不能发送空消息!);CEdit *pEdit = (CEdit*)GetDlgItem(IDC_EDIT_MESSAGE);pEdit-SetFocus();return;Header head;head.type = SEND_MESSAGE;head.le

29、n = m_strMessage.GetLength();CTime time = CTime:GetCurrentTime();CString t = time.Format(%H:%M:%S);CString nikeName = theApp.m_strName;CString str = nikeName + + t + rn + +m_strMessage;m_pSocket-Send(char *)&head,sizeof(Header); /将发送时间和收信客户信息发至服务器if(m_pSocket-Send(LPCTSTR)str, str.GetLength() /发送信息内

30、容m_strMessage = ;UpdateData(FALSE);CEdit *pEdit = (CEdit*)GetDlgItem(IDC_EDIT_MESSAGE);pEdit-SetFocus();elseAfxMessageBox(_T(网络传输错误!); (5)服务器接收消息并转发,具体代码如下:void CClientSocket:OnReceive(int nErrorCode) char buff1sizeof(Header);memset(buff1, 0, sizeof(buff1);Receive(buff1,sizeof(buff1);Header *header

31、= (Header*)buff1;int length = header-len;char type = header-type;if(type = LOGIN_IO) /如果收到的是登录信息char buff1000; memset(buff,0,sizeof(buff); Receive(buff,length); /接受客户登录信息CTime time = CTime:GetCurrentTime(); /获取当前系统时间 CString t = time.Format(%Y-%m-%d %H:%M:%S); /时间格式CEdit *p_Edit = (CEdit *):AfxGetMa

32、inWnd()-GetDlgItem(IDC_EDIT_INFO);CString strTemp = t + : + CString(buff) + 进入rn; /显示登录信息p_Edit-ReplaceSel(strTemp); /更新在线客户列表 m_strName = buff; m_dlgServer-UpdateUser(this);if(type = SEND_MESSAGE) /如果接受的是客户发送信息char buff1000; memset(buff,0,sizeof(buff); Receive(buff,sizeof(buff); /接收消息内容CClientSocke

33、t *curr = NULL;POSITION pos = clist-GetHeadPosition();while (pos != NULL) /将消息发至在线客户curr = (CClientSocket *)clist-GetNext(pos);curr-Send(char *)header,sizeof(Header);curr-Send(buff, sizeof(buff);CSocket:OnReceive(nErrorCode); (6)客户端接收服务器转发的消息,具体代码如下: BOOL CMyChatDlg:GetMessage() /接受服务器转发的信息char buff

34、1000;memset(buff,0,sizeof(buff);m_pSocket-Receive(buff, sizeof(buff),0);CString strTemp = buff;strTemp += _T(rn);m_MessageList.ReplaceSel(strTemp); /显示接受到的信息return TRUE; (7)客户下线后,服务器将下线的客户从客户列表中删除,具体代码如下: void CClientSocket:OnClose(int nErrorCode) /服务器通过失去连接错误码获知下线的客户POSITION pos = clist-Find(this);

35、if(pos != NULL)clist-RemoveAt(pos); /将下线客户信息从列表中删除CTime time = CTime:GetCurrentTime();CString t = time.Format(%Y-%m-%d %H:%M:%S);CEdit *p_Edit = (CEdit *)m_dlgServer-GetDlgItem(IDC_EDIT_INFO);CString strTemp = t + : + this-m_strName + 离开rn;p_Edit-ReplaceSel(strTemp); /显示客户下线信息m_dlgServer-UpdateUser(

36、this);this-Close(); /关闭与下线客户连接的套接字delete this;CSocket:OnClose(nErrorCode); (8)其他客户下线后,客户端更新在线用户列表,具体代码如下:void CMyChatDlg:UpdateUser()char buff1000;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

37、.GetLength(); i+ ) /查找当前在线用户if(i != (user_info.GetLength() - 1)if ( user_infoi=& )b +;elsearrayb = arrayb + user_infoi;m_UserList.ResetContent();for(int j=0; jb+1; j+) /更新在线用户列表m_UserList.AddString(arrayj);5总结 经过了整整3个星期的忙碌,终于完成了课程设计。在这段时间里体验了无数的酸甜苦辣,从解决不了细小问题的苦恼到问题最终解决的喜悦。一直伴随着整个设计过程。整个设计过程是不断学习,不断发现问题、分析问题、解决问题的过程。使我受益良多。设计期间有许多的感触、想法、经验、教训,对以后的学习、工作有很大的益处。 这次的课程设计是简单聊天程序,在平日的生活学习中,可以说QQ等即时通讯软件已占据重要的位置,也深受大家的喜爱,所以这个课程设计很有

温馨提示

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

最新文档

评论

0/150

提交评论