资源描述
沈航北方科技学院课程设计说明书 课程名称 网络应用开发实战 系 别 专 业 班 级 学 号 学生姓名 指导教师 2015年1月摘 要随着科技的发展和社会的不断进步,我国的科研成果也越来越多。要想在科技方面走在世界前列,必须要有自己的科研管理方案。由此看来,一种对科研信息管理行之有效的手段显得尤为重要,出色的科研信息管理会给整个社会带来无穷的经济效益和社会效益。计算机的最大好处在于利用它能够进行更好的通信。使用计算机进行通信控制,不仅提高了工作效率,而且大大的提高了其安全性。尤其对于复杂的通信与开发,计算机能够充分发挥它的优越性。关键词:TCP,服务器,客户端TCP客户端与服务器编程杨 阔目 录摘 要I1 绪论11.1开发背景11.2开发意义11.3开发目的21.4开发要求22 可行性分析32.1技术可行性分析32.2操作可行性分析3 2.3经济可行性分析.43 需求分析54系统设计64.1系统结构64.2执行步骤75详细设计95.1 模型结构95.2功能分析95.3设计与实现116 系统调试与测试136.1系统调试136.2系统测试137结 论14参考文献15附录1用户手册16附录2源程序171 绪论随着科学技术的不断提高,计算机科学日渐成熟,其强大的功能已被人们深刻认识。它已进入人类社会的各个领域并发挥着越来越重要的作用。作为计算机应用的一部分,使用计算机实现TCP客户端与服务器的编程,具有很大的意义。例如,使用方便、可靠性高、保密性好、寿命长、成本低等。这些优点能够极大地提高效率,这是与世界接轨的重要条件。因此要开发一个TCP客户端和服务器程,利用现代化方法进行通信。1.1开发背景当今时代是飞速发展的信息时代,在各行各业中离不开网络,这正是计算机被广泛应用的原因。计算机的最大好处在于利用它能够进行更好的通信。使用计算机进行通信控制,不仅提高了工作效率,而且大大的提高了其安全性。尤其对于复杂的通信与开发,计算机能够充分发挥它的优越性。设计一个TCP的服务器与客户端程序,目的是为了更快,更好地使用TCP网络进行上层业务开发。1.2开发意义在目前的情形下,从所现有的实际条件出发,利用计算机设计一个TCP服务器和客户端程序,实现客户端与服务器的连接通信。为上层业务开发减少负担,从根本上做到科学化、高效率化这一目的。 1.3开发目的随着社会的发展,在信息社会中,信息的获取、处理、交流和决策都需要高质量的计算机软件来完成。作为计算机应用的一部分,使用计算机实现TCP客户端与服务器的编程,具有很大的意义。例如使用方便、可靠性高、保密性好、寿命长、成本低等。这些优点能够极大地提高效率,这是社会进步与国际接轨的表现。设计一个TCP的服务器与客户端程序,目的是为了更快,更好地使用TCP网络进行上层业务开发,使TCP编程更加方便。1.4开发要求利用流式套接字编写TCP客户机和服务器程序。主要包含的功能如下:服务器功能:从端口6000接收客户发送来的数据;只要有客户请求连接,服务器就接受连接;连接成功后,服务器端显示客户的IP地址和端口号,并向请求连接的客户发送“I am a server!”信息;如果发送过程正确完成,显示所发送的字节数。客户机功能:向服务器发出连接请求;连接成功后,接收并显示从服务器收到的信息内容和字节数。2 可行性分析可行性分析(feasibility study ),是世界上普遍采用的一种研究工程项目是否可行的科学。它通过各种有效的方法,对工程项目进行分析,从技术、经济、财务等方面加以评价,最终给投资决策者提供是否选择该项目进行投资的依据。2.1技术可行性分析当今社会计算机已经相当普及,人们的日常生活基本离不开它。TCP服务器和客户端编程主要实现从端口6000接收客户发送来的数据,如果有客户请求连接,服务器就接受连接;连接成功后,服务器端显示客户的IP地址和端口号,并向请求连接的客户发送“I am a server!”信息;如果发送过程正确完成,显示所发送的字节数对客户信息的管理,内容并不复杂。因此制作一个TCP客户端和服务器程序是有必要的。综上所述,科研管理信息系统的开发从数据库技术、软件技术、硬件技术方面均具有可行性。2.2操作可行性分析根据要求本系统需要操作界面友好,界面美观,使用简单方便,系统稳定性好,安全可靠。本系统是高校科研管理信息系统,获取的本机名,用来解析得到本机的IP地址的;接着就绑定IP地址成功,然后服务器就处于监听状态,等待客户端的连接。也就是接下来就是TCP/IP的三次握手的操作,该操作成功了服务器和客户端就可以进行通信了。综合科研管理信息系统的各项简洁操作,本系统在操作上是可行的。2.3经济可行性分析硬件方面, 一台普通的计算机上就可以实现本次编程,一般的I5双核四线程或者AMD的四核CPU,可以满足要求了。对于复杂的通信与开发,计算机能够充分发挥它的优越性。总的来说,此次编程对电脑要求不会很高,后期运行对系统也无过高要求。所以,从经济角度来讲,开发本程序是可行的。3 需求分析TCP协议提供的是可靠的、面向连接的传输控制协议,即在传输数据前要先建立逻辑连接,然后再传输数据,最后释放连接3个过程。TCP提供端到端、全双工通信;采用字节流方式,如果字节流太长,将其分段;提供紧急数据传送功能。本次课程设计的题目是TCP服务器与客户端软件,使用TCP协议实现客户端与服务器之间的通信。软件针对局域网内部用户,实现用户间的即时通信。需要分别实现服务器端和客户端的软件设计。TCP要求在发送数据之前必须打开连接。服务器应用程序必须执行一个称作被动打开(passive open)的操作,以利用一个已知的端口号创建一个链接,这是,服务器并不是对网络进行呼叫,而是侦听并等待引入的请求。客户应用程序必须执行一个主动打开(active open),为此,它向服务器应用程序发送一个同步序列号(SYN)以标识连接。客户应用程序可以将动态端口号作为本地端口使用。服务器必须向客户发送一个确认(ACK)以及服务器的序列号(SYN)。随后,客户回复一个ACK,这样就建立了链接。4系统设计系统设计要回答“怎么做”,即如何实现系统说明书规定的系统功能。在这一阶段,要根据实际的技术条件,经济条件和社会条件确定系统的实施方案,即系统的物理模型。4.1系统结构套接字这个术语并没有定义某个协议:它具有两层含义,但两者都与一个协议相关。第一个含义是套接字编程API,它最初由伯克利大学为BSD UNIX而创建。BSD套接字在经过修改后被用作Windows环境的编程接口(并且被命名为WinSock)。WinSock API被包装在System.Net.sockets命名空间的.NET类中。Windows Sockets 是一个独立于协议的编程接口,用于编写网络应用程序。套接字的第二层含义表示一个用于在进程间进行通信的终端。在TCP/IP中,每个终端都与一个IP地址和一个端口号绑定。我们必须对流式套接字和数据报套接字这两种类型进行区分。流失套接字用TCP/IP协议来使用面向连接的通信。使用 TCP 套接字编程可以实现基于 TCP/IP 协议的面向连接的通信,它分为 服务器端和客户端两部分,其主要实现过程如图4.1 所示。 图4.1 4.2执行步骤服务器端步骤: 使用socket()创建套接字; 将创建的套接字绑定到指定的地址结构; 设置套接字为监听模式,进入被动接受连接状态; 接受请求,建立连接; 读写数据; 终止连接。 客户端步骤: 创建套接字; 与远程服务器建立连接; 读/写数据; 终止连接。 5详细设计详细设计的主要任务是设计每个模块的实现算法、所需的局部数据结构。详细设计的目标有两个:实现模块功能的算法要逻辑上正确和算法描述要简明易懂。5.1 模型结构客户机/服务器模型,又称为Client/Server模型,简称C/S架构。C/S计算技术在信息产业当中占有重要的地位。这种客户机/服务器模型是一种非对称式编程模式。该模式的基本思想是把集中在一起的应用划分成为功能不同的两个部分,分别在不同的计算机上运行,通过它们之间的分工合作来实现一个完整的功能。对于这种模式而言其中一部分需要作为服务器,用来响应并为客户提供固定的服务;另一部分则作为客户机程序用来向服务器提出请求或要求某种服务。在此“服务器”是指能在网络上提供服务的任何程序。服务器接受网络上的请求,完成服务后将结果返回给申请者。对于简单的服务,把每个请求用一个IP数据报发给服务器,服务器用另一个数据报返回响应。严格说来,客户机/服务器模型并不是从物理分布的角度来定义,它所体现的是一种网络数据访问的实现方式。采用这种结构的系统目前应用非常广泛。各种网络服务器基本都遵循同样的算法:创建一个端口(Port),接受从网络上来的客户服务请求,完成计算后把结果返回给客户,如此反复。5.2功能分析服务器与客户端的交互过程如图所示: 图5.1建立连接部分图5.2等待数据传输部分图5.3关闭连接部分5.3设计与实现本程序实现一个客户端基础类(TCPClientBase)和服务器端基础类(TCPServerBase),其中客户端基础类有两种方式,一种是使用于单独的客户端的单元;另一种使用与服务器端接收一个链接后的单元流程图如图5.4所示。图5.4流程图 6 系统调试与测试系统调试与测试主要是指通过对系统的反复调试与测试,找出系统还存在的错误或不足,最后纠正错误或不足,期望系统达到最优效果。6.1系统调试调试过程主要是运行编制好的程序,然后遇到错误后根据系统的提示,找到相关的问题所在。本系统调试过程中遇到问题、原因和解决方法如下面介绍。出现的问题:字符信息不能正常显示从程序中读出来的信息是乱码,只有数字读出来是正常的,而对于字符读出来却都是乱码。经过查询资料和反复尝试,终于能正常显示。原来是忘记了加上引号,改正后,显示正常。6.2系统测试测试是程序的一种执行过程,目的是尽可能发现并改正被测试程序中的错误,提高程序的可靠性。它是程序生命周期中一项非常重要且非常复杂的工作,对软件可靠性保证具有极其重要的意义。在目前形式化方法和程序正确性证明技术还无望成为实用性方法的情况下,软件测试在将来相当一段时间内仍然是软件可靠性保证的有效方法。软件工程的总目标是充分利用有限的人力和物力资源,高效率、高质量地完成软件开发项目。不足的测试势必使软件带着一些未揭露的隐藏错误投入运行,这将意味着更大的危险让用户承担。过度测试则会浪费许多宝贵的资源。到测试后期,即使找到了错误,然而付出了过高的代价。调试过程主要是运行编制好的程序,然后遇到错误后根据系统的提示,找到相关的问题所在。经过不断的努力,本系统调试过程中遇到的问题终于一一解决。7结 论经过将近半个月的设计与开发,TCP客户端与服务器程序基本开发完毕,其功能基本符合需求,能够完成客户端与服务器的通信。对于数据的一致性的问题也通过程序进行了有效的解决。系统设计为整个程序构建了骨架,各个功能模块实现各个细节部分。利于使用者在需要之时快速连接服务器。但是由于课程设计时间较短,所以该系统还有许多不尽人意的地方比如通信方式比较单一,用户界面不够美观,帮助系统不够完善,出错处理不够等多方面问题。这些都有待于进行进一步改善。参考文献 1 龚沛曾,杨志强.C/C+程序设计教程. 高等教育出版社,2004年2 谭献海网络编程技术及应用,北京:清华大学出版社,2006.123 吴功宜,董大凡.计算机网络高级软件编程技术,北京:清华大学出版社,2008.1附录1用户手册点击运行,弹出程序界面,如图1所示。图1程序运行界面图中显示了TCP客户端与服务器的程序运行界面,接受信息并统计出发送信息的字节数的情况。附录2源程序 主要模块源代码清单:# include # include #pragma comment(lib, WS2_32) / 链接到WS2_32.lib#define PORT 6000 / 此服务器监听的端口号#define BUFFERLEN 1024 /数据缓冲区大小void main() /通过载入Winsock库,来使用Winsock的相关函数 WSADATA wsaData; /用来返回Winsock库的详细信息 WORD version = MAKEWORD(2, 2); int ret = WSAStartup(version, &wsaData); if(ret != 0) printf( 加载Winsock库错误! n); return ; SOCKET sListen;/声明服务器端监听套接 sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if (INVALID_SOCKET=sListen) printf(创建套接字失败:%dn,WSAGetLastError(); return; /设置服务器端地址 struct sockaddr_in addrSrv; addrSrv.sin_family=AF_INET; addrSrv.sin_port=htons(PORT); addrSrv.sin_addr.s_addr=inet_addr(127.0.0.1); if (SOCKET_ERROR=bind(sListen,(sockaddr *)&addrSrv,sizeof(addrSrv) printf(绑定失败:%dn,WSAGetLastError(); return; if (SOCKET_ERROR=listen(sListen,5) printf(监听失败:%dn,WSAGetLastError(); return; printf( TCP服务器正在运行.n n); SOCKET SockConn; sockaddr_in addrClient;/声明存放来自客户端的地址 int addrlen=sizeof(addrClient);/初始化客户端地址长度 char sendBufBUFFERLEN;/用户发送缓冲区 char recvBufBUFFERLEN;/用户接收缓冲区 int sendlen;/发送数据长度 int recvlen;/接收数据长度 SOCKET sockClient;/声明客户端套接字 /socket(协议地址族,套接字类型,协议);创建套接字 sockClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if ( INVALID_SOCKET =sockClient) printf( 创建套接字失败:%dn,WSAGetLastError(); return ; if(SOCKET_ERROR=connect(sockClient,(sockaddr*)&addrSrv,sizeof(addrSrv) printf(连接失败:%dn,WSAGetLastError(); return; printf(连接到服务器n); SockConn=accept(sListen,(sockaddr*)&addrClient,&addrlen); if (INVALID_SOCKET=SockConn) printf(接受客户端连接失败:%dn,WSAGetLastError(); / continue; sprintf(sendBuf,I am a client!); /while(true) sendlen=send(sockClient,sendBuf,strlen(sendBuf)+1,0); printf(发送到服务器的数据:%s ; 字节数%dn,sendBuf,sendlen); if (SOCKET_ERROR=sendlen) printf(发送到服务器失败:%d n,WSAGetLastError(); return; printf(客户端的连接IP:%s,端口:%dn, inet_ntoa(addrClient.sin_addr), ntohs(addrClient.sin_port); printf(发送到服务器的数据:%s ; 字节数%dn,sendBuf,sendlen); recvlen=recv(SockConn,recvBuf,sizeof(recvBuf),0); if (SOCKET_ERROR=recvlen) printf(从客户端接收数据失败:%dn,WSAGetLastError(); /continue; sprintf(sendBuf,I am a Server!); printf(接收到客户端的数据:%s ; 字节数%dn,recvBuf,recvlen); sendlen=send(SockConn,sendBuf,strlen(sendBuf)+1,0); if (SOCKET_ERROR=sendlen) printf(向客户端发送数据失败:%dn,WSAGetLastError(); /continue; printf(发送到客户端的数据:%s ; 字节数%d n n,sendBuf,sendlen); closesocket(SockConn); /关闭已连接套接字 / recvlen=recv(sockClient,recvBuf,sizeof(recvBuf),0); if(SOCKET_ERROR=recvlen) printf(从服务器接收失败:%dn,WSAGetLastError(); return; printf(接收到服务器的数据:%s ; 字节数%dn,recvBuf,recvlen);/ closesocket(sockClient);/关闭套接字 /closesocket(sockClient); / closesocket(sListen);/关闭监听套接字 WSACleanup();/释放Winsock库完成日期:2015年1月16日
展开阅读全文