简易代理服务器的设计毕业设计论文.doc

上传人:文库蛋蛋多 文档编号:3990591 上传时间:2023-03-30 格式:DOC 页数:32 大小:448.50KB
返回 下载 相关 举报
简易代理服务器的设计毕业设计论文.doc_第1页
第1页 / 共32页
简易代理服务器的设计毕业设计论文.doc_第2页
第2页 / 共32页
简易代理服务器的设计毕业设计论文.doc_第3页
第3页 / 共32页
简易代理服务器的设计毕业设计论文.doc_第4页
第4页 / 共32页
简易代理服务器的设计毕业设计论文.doc_第5页
第5页 / 共32页
点击查看更多>>
资源描述

《简易代理服务器的设计毕业设计论文.doc》由会员分享,可在线阅读,更多相关《简易代理服务器的设计毕业设计论文.doc(32页珍藏版)》请在三一办公上搜索。

1、毕业设计(论文)简易代理服务器的设计论文作者姓名:申请学位专业:申请学位类别:指导教师姓名(职称):论文提交日期:简易代理服务器的设计摘 要代理服务器是介于浏览器和Web服务器之间的一台服务器,它的功能是代理网络用户去取得网络信息。它的工作原理是,接收客户机的数据连接请求,并将请求传给Web服务器;再从Web服务器接收返回的数据,最后把数据传给客户端显示。本论文讲述的是关于一个简单的代理服务器的实现,在实现中采用客户机/服务器结构模型开发应用程序,基于一般的访问浏览速度慢、效率底、安全功能不强等原因,将以简单、合理、有效为原则;为了方便分析和设计,系统设计中设置不同的状态量用于标识客户机、代理

2、服务器及服务器间的联结状态。在保证系统基本功能的同时,使用多线程机制使得代理系统有更好的延续性。此代理系统具有简单,易用,网络化等优点,能够完成一般的HTTP访问代理服务。关键词:客户机/服务器结构;多线程;套接字;代理服务器TheDesignofSimpleProxyServerAbstractThe proxy server is a server which situates between the browser and a Web server. Its principle of work is, it receives the connection request from the

3、 client, and hands down the requested to the Web server, then receives data which is returned from the Web server., finally hands it down the data to the client. In the realization, it adopts Client/Server structural model to develop application. Because of browse speed slow, low efficient and not s

4、afe enough, it takes simple, reasonable and effective as the principle. In the system design, it sets different states to identify client, proxy server and the connective state between servers. When the systems basic function are guaranteed, it use the multithreading to enable the proxy server to ha

5、ve a better continuous feature. This proxy system has the merit such as simple, easy to use and so on, and it can complete the proxy of general HTTP visit.Key words: Client / Server architecture;Multithreading;Socket;Proxy Server目 录论文总页数:20页1引言11.1课题背景11.2本课题研究的意义11.3本课题的研究方法12理论基础22.1代理服务器22.2目前的代理

6、服务技术32.3Socket 面向连接的编程模型42.4Winsock库52.4.1winsock的寻址方式52.4.2字节顺序62.5系统基本套接字调用62.5.1创建和关闭套接字socket()和closesocket()62.5.2指定本地地址bind()62.5.3设置监听状态-listen()62.5.4建立套接字连接connect()和accept()62.5.5收发数据-send()和recv()73设计方案73.1基本函数设计73.2多线程流程84服务器的实现84.1环境创建84.2功能实现94.2.1数据变量定义94.2.2启动代理服务器104.2.3请求处理过程114.2.

7、4请求响应134.2.5关闭服务器154.2.6控制主函数155测试结果15结 论17参考文献18致 谢19声 明201 引言1.1 课题背景普通的因特网访问是一种典型的客户机与服务器结构,而代理服务器将运行于客户机与服务器之间,它作为Internet/Intranet上常用的一种服务器,通常配置在Intranet连接Internet的出口处,主要实现代理传输服务。可以这样认为,代理是双向的。即对于内部网上的用户来说,代理服务器可看作是一个外部网的代理;对于外部网络来说,代理服务器可以看作一个要访问外部网的客户。正是由于代理服务器的这种控制方式,可以使用它提高客户访问外网的效率、节省网络带宽,

8、增强网络安全性以及减少网络投资等。代理服务器从提出到现在,不断的经历着内容更进和技术的革新,各种代理服务器产品更是层出不穷。不难看出,代理服务器在我们信息时代的生活中扮演着越来越重要的作用。1.2 本课题研究的意义随着Internet与Intranet的飞速发展,作为连接Internet与Intranet的桥梁,代理服务器在实际应用中发挥着极其重要的作用。它可用于多个目的,最基本的功能是连接;此外还包括安全性、缓存、内容过滤、访问控制管理等功能。在代理服务器的众多功能中,安全性是一个突出且敏感的功能。绝大多数企业、部门在使用代理服务器的时候,都会考虑这个问题,把它作为选购代理服务器产品的重要依

9、据。目前市场上流行的代理服务器,像Microsoft Proxy Server、Netscape Proxy Server、Win Gate等国外的产品,功能和性能等方面都还不错,我们正好可以通过借鉴它们产品的优点,开发一个具有自主产权的代理服务器产品。而且从保证安全性的角度出发,我们也很有必要开发一个自己的代理服务器。除了上面的因素外,通过一个简单的代理程序的开发,我们能从实现过程中学习到网络通信和网络编程的基础知识,加深理解和掌握我们所使用的开发语言。另外,我们也能从中学习到正确的程序开发流程,积累程序开发经验,为以后更深课题的研究打好基础。1.3 本课题的研究方法此代理服务器系统将是建立

10、在Windows NT平台上的网络应用程序设计。由于需要服务器为其他许多称为客户的主机提供服务,而客户主机又可以随时打开和关闭,在选择网络应用程序体系结构时就采用支持这些特点的客户机/服务器结构。还将运用Windows下网络编程的标准接口WinSock ,因为它允许两个或多个应用程序在相同机器上,或者是通过网络相互交流,它是真正协议无关的接口。为了便于直接使用Windows提供的网络编程接口,我们使用Microsoft Visual C+ 6.0作为开发工具,利用MFC类库中提供的两个Socket类CAsyncSocket和Csocket。使用这两个Socket类,我们可以运用面向对象的方法来

11、进行Socket编程,而且它们还分别在较低和较高层次上封装了Windows Sockets API,为程序员开发Socket程序提供了便利。2 理论基础2.1 代理服务器代理服务器的英文全称是Proxy Server,其功能就是代理网络用户去取得网络信息。形象的说:它是网络信息的中转站。很多人不知不觉中就在用代理服务器共享上网,比如sygate,wingate,isa,ccproxy,NT系统自带的网络共享等,它们可以提供企业级的文件缓存,复制和地址过滤等服务。在一般情况下,我们使用网络浏览器直接去连接其他Internet站点取得网络信息时,须送出Request信号来得到回答,然后对方再把信息

12、以bit方式传送回来。代理服务器是介于浏览器和Web服务器之间的一台服务器,有了它之后,浏览器不是直接到Web服务器去取回网页而是向代理服务器发出请求, Request信号会先送到代理服务器,由代理服务器来取回浏览器所需要的信息并传送给你的浏览器。而且,大部分代理服务器都具有缓冲的功能,就好像一个大的Cache,它有很大的存储空间,它不断将新取得数据储存到它本机的存储器上,如果浏览器所请求的数据在它本机的存储器上已经存在而且是最新的,那么它就不重新从Web服务器取数据,而直接将存储器上的数据传送给用户的浏览器,这样就能显著提高浏览速度和效率。更重要的是:Proxy Server (代理服务器)

13、是 Internet链路级网关所提供的一种重要的安全功能,它的工作主要在开放系统互联(OSI)模型的对话层。主要的功能有:1、连接Internet与Intranet充当防火墙:因为所有内部网的用户通过代理服务器访问外界时,只映射为一个IP地址,所以外界不能直接访问到内部网;同时可以设置IP地址过滤,限制内部网对外部的访问权限;另外,两个没有互联的内部网,也可以通过第三方的代理服务器进行互联来交换信息。2、节省IP开销:前面所讲,所有用户对外只占用一个IP,所以不必租用过多的IP地址,降低网络的维护成本。这样,局域局内没有与外网相连的众多机器就可以通过内网的一台代理服务器连接到外网,大大减少费用

14、。当然也有它不利的一面,如许多网络黑客通过这种方法隐藏自己的真实IP地址,而逃过监视。3、提高访问速度:本身带宽较小,通过带宽较大的proxy与目标主机连接。而且通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,从而达到提高访问速度的目的。4、防止攻击:隐藏自己的真实地址信息,还可隐藏自己的IP,防止被黑客攻击。通过分析指定IP地址,可以查询到网络用户的目前所在地。例如,大家在一些论坛上看到,论坛中明确标出了发帖用户目前所在地,这就是根据论坛会员登录时的IP地址解析的。还有平日里我们最为常

15、用的显IP版QQ,在“发送消息”窗口中,可以查看对方的IP及解析出的地理位置。而当我们使用相应协议的代理服务器后,就可以达到隐藏自己当前所在地地址的目的了。5、突破IP访问限制:使用它可以访问一些有IP禁止访问的服务器,因为封锁只禁止了你和目标服务器的连接,但并没有禁止你与代理服务器的连接 以及代理服务器与目标服务器的连接。代理服务器有许多种,大体来说有HTTP,FTP,SOCKS代理三种,其中又分透明代理和不透明代理。其中透明代理一般是网关,是硬件,所以不讨论透明代理。当机器通过代理服务器上网时。通讯是分两次的,先是机器和代理服务器通讯,再是代理服务器和目的地址通讯。机器和代理服务器通讯时,

16、目的IP是代理服务器的IP。代理服务器和目的地址通讯时,源IP是代理服务器的IP,当然外部的数据也是一样的。在内网中,出现的IP数据,全是内网和代理服务器的IP。因此,从IP包头是看不出任何与外面通讯的信息的。只有从数据中才能看到。2.2 目前的代理服务技术代理服务技术是在一台PC机上安装一套代理软件,主要用于用户对Internet资源的访问。ICS即Internet连接共享(Internet Connection Sharing)的英文简称,是Windows系统针对家庭网络或小型的Intranet网络提供的一种Internet连接共享服务。它实际上相当于一种网络地址转换器,所谓网络地址转换器

17、就是当数据包向前传递的过程中,可以转换数据包中的IP地址和TCP/UCP端口等地址信息。有了网络地址转换器,家庭网络或小型的办公网络中的电脑就可以使用私有地址,并且通过网络地址转换器将私有地址转换成ISP分配的单一的公用IP地址从而实现对Internet的连接。ICS方式也称之为Internet转换连接。例如有软件:Wingate,Winproxy等。NAT即网络地址转换(Network Address Translator),从广义上讲,ICS也是使用了一种NAT技术,不过我们这里讨论的NAT是指将运行Windows 2000 Server的计算机作为IP路由器,通过它在局域网和Intern

18、et主机间转发数据包从而实现Internet的共享。NAT方式也称之为Internet的路由连接。网络地址转换NAT通过将专用内部地址转换为公共外部地址,对外隐藏了内部管理的IP地址。这样,通过在内部使用非注册的IP地址,并将它们转换为一小部分外部注册的IP 地址,从而减少了IP 地址注册的费用。同时,这也隐藏了内部网络结构,从而降低了内部网络受到攻击的风险。例如有软件:WinRoute,Sygate。2.3 Socket 面向连接的编程模型代理服务器既然是双向的客户机/服务器模型,它工作时通常有一个公共的规则需要遵守,通信双方需要共同遵守这个规则才能保证通信的有效进行,如需要量传输大量语音信

19、息时须采用一种无须建立连接的传输方式,在这种方式下,数据可以以较快的速度传输。而当需要确保数据准确无误地到达时,则应采用面向连接的传输方式。代理服务器就要求采用这种方式,在这种模型下,当服务器程序的套接字创建并初始化完毕时,它先进入休眠状态,直到有客户机向该服务器程序提出连接请求。这时,服务器程序被“唤醒”,并开始响应客户机提出的连接请求。这时双方协商数据由谁来接收和由谁来发送,在数据传输完毕时,双方再分别关闭连接,释放因创建套接字而占用的资源,面向连接的编程模型示意图如下: 图1面向连接的编程模型上面的示意图向我们显示了面向连接的服务器程序和客户程序的创建与结束过程。首先服务器端创建监听套接

20、字,并为它关联一个本地地址(指定IP地址和端口号),然后进入监听状态准备接收客户端的连接请求。为了接受客户端的连接请求,服务器必须调用accept函数。客户端创建套接字后即可调用connect函数去试图连接服务器监听套接字。当服务器端的accept函数返回后,connect函数也返回。此时客户端使用socket函数创建的套接字,服务器端使用accept函数创建的套接字,双方就可以通信了。当数据完成交换后,客户程序和服务器程序都会分别关闭创建的套接字句柄以完成双方的对话,至此程序服务结束。2.4 Winsock库Winsock是Windows下网络编程的标准接口,它允许两个或多个应用程序在相同机

21、器上,或者是通过网络相互交流。Winsock库的装入时是对Winsock DLL版本的进行选择,每个Winsock应用程序都必须加载与之相应的版本的Winsock DLL。如果没有加载,将返回SOCKET_ERROR,加载的函数是WSAStartup,其定义如下:int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);它的第一个参数就是要加载的库版本,第二个参数是用来返回DLL库的详细信息的。2.4.1 winsock的寻址方式因为Winsock要兼容多个协议,所以必须使用通用的寻址方式。TCP/IP使用地址和端口号来指定一个地址,

22、但是其它协议也许采用不同的形式。如果Winsock强迫使用特定的寻址方式,添加其他协议就不大可能了。在Winsock中,应用程序员通过SOCKADDR_IN结构来指定IP地址和端口号。定义如下:Struct sockaddr_inshort sin_family;u_short sin_port;struct in_addr sin_addr;har sin_zero8;应用程序可以使用inet_addr函数将一个小数点分隔的十进制IP地址字符串转化成由32位二进制数表示的IP地址。inet_ntoa函数将一个网络字节顺序的32位IP地址转化字符串。注意:inet_addr返回的32位二进制数

23、是用网络顺序存储的。2.4.2 字节顺序字节顺序是长度跨越多个字节的数据被存储的顺序,分为小尾顺序和大尾顺序,TCP/IP统一规定使用大尾顺序方式传输数据,即网络字节顺序,它的字节顺序是最重要的字节首先存储。Winsock提供了一些函数来处理本地机器的字节顺序和网络字节顺序的转换,htons将主机字节顺序转化到TCP/IP网络字节顺序,ntohs将网络字节顺序转化到主机字节顺序,此外还有htonl和ntohl。这API数据都是平台无关的。使用它们可以保证程序正确运行在所有机器上。2.5 系统基本套接字调用2.5.1 创建和关闭套接字socket()和closesocket()应用程序在使用套接

24、字前,首先必须拥有一个套接字,系统调用socket()向应用程序提供创建套接字的手段,如果成功将返回套接字句柄,如果创建失败,返回INVALID_SOCKET(即-1)。当不使用此套接字时,应该用closesocket函数关闭套接字,如果没有错误发生,函数返回0,否则返回SOCKET_ERROR。2.5.2 指定本地地址bind()当一个套接字用socket()创建后,存在一个名字空间(地址族),但它没有被命名。bind()将套接字地址(包括本地主机地址和本地端口地址)与所创建的套接字号联系起来,即将名字赋予套接字,以便能够有效地标识套接字。它用在没有建立连接的套接字上,如果没有错误发生,bi

25、nd()返回0。否则返回值SOCKET_ERROR。当然,客户端程序也可以在不显示绑定地址和端口号的情况下发送数据或者连接。这时系统会默认地为套接字绑定一个本地端口值。注意:地址在建立套接字通信过程中起着重要作用,程序使用中通常靠填充sockaddr_in结构来绑定套接字到本地地址。绑定到套接字上的本地名称包括主机地址、协议号和端口号3部分。2.5.3 设置监听状态-listen()Listen函数设置套接字进入监听状态。为了接受连接,首先使用socket函数创建套接字,然后使用bind函数将它绑定到本地地址,再用listen函数为到达的连接指定backlog,最后使用accept函数接受请求

26、的连接。Listen函数仅应用在支持连接的套接字上,如SOCK_STREAM类型。函数执行成功后,套接字将进入被动模式,到来的连接会通知要排队并等候接受处理。在同一时间处理多个连接请求的服务器通常使用listen函数,如果一个连接请求到达并且排队也满,客户端将接收错误。2.5.4 建立套接字连接connect()和accept()这两个系统调用用于完成一个完整相关的建立,用于客户机与网络中的服务器建立连接时,用connect()这个调用连接将请求发到侦听方。之后,服务端就会调用accept(),而在调用accept ()的参数前应该先调用过listen(),Accept函数定义如下:SOCKE

27、T accept(SOCKET soc, struct sockaddr * addr, int * addrlen);2.5.5 收发数据-send()和recv()对流套接字来说,一般使用send和recv函数来收发数据。Send函数在一个连接的套接字上发送缓冲区内的数据,返回发送数据的实际字节数。Recv函数从对方接收数据,并将其存储到指定的缓冲区。Flags参数在这两函数中通常设为0。3 设计方案3.1 基本函数设计我们根据上面讨论的代理服务器内容容易画出代理服务器的简单流程模型:图2 代理服务器的流程从图中看出,我们需要设计的基本功能函数为ClientToProxy和ProxyToS

28、erver。其中,ClientToProxy用于实现收取Client数据请求并传给Server;ProxyToServer用于接收Server的数据、传给请求Client。在处理数据请求的过程中,我们必须知道Server的地址,这是非常重要的。这需要设计一个函数来解析地址,设计过程中用ReceiveInformation函数来实现。另外,任何Windows Socket函数对IP地址和端口号的引用和传送给Windows Sockets函数的IP地址和端口号均是按照网络顺序组织的,这也包括了sockaddr_in结构这一数据类型中的IP地址域和端口域(但不包括sin_family域)。考虑到一个

29、应用程序通常用“时间”服务对应的端口来和服务器连接,而服务器提供某种机制来通知用户使用另一端口,因此gethostbyname()函数返回的端口号已经是网络顺序了,可以直接用来组成一个地址,而不需要进行转换。如果用户输入一个数,而且指定使用这一端口号,则应用程序必须在使用它建立地址以前,把它从主机顺序转换网络顺序(使用htons()函数)。相应地,应用程序希望显示包含于某一地址中的端口号,这一端口号就必须在被显示前从网络顺序转换到主机顺序(ntohs)。3.2 多线程流程由于代理服务器和大多数服务器一样,如果要处理多个请求,它应该使用多线程。其基本规划如下:1. 等待来自客户(Web浏览器)的

30、请求2. 启动一个新的线程,以处理客户连接请求3. 读取浏览器请求的第一行(该行内容包含了请求的目标URL)4. 分析请求的第一行内容,得到目标服务器的地址和端口5. 打开一个通向目标服务器(或下一个代理服务器,如合适的话)的Socket6. 把请求的第一行发送到输出Socket7. 把请求的剩余部分发送到输出Socket8. 把目标Web服务器返回的数据发送给发出请求的浏览器当然,如果考虑细节的话,情况会更复杂一些。实际上,这里主要有两个问题要考虑:第一,从Socket按行读取数据最适合进一步处理,但这会产生性能瓶颈;第二,两个Socket之间的连接必需高效。有几种方法可以实现这两个目标,但

31、每一种方法都有各自的代价。例如,如果要在数据进入的时候进行过滤,这些数据最好按行读取;然而,大多数时候,当数据到达代理服务器时,立即把它转发出去更适合高效这一要求。另外,数据的发送和接收也可以使用多个独立的线程,但大量地创建和拆除线程也会带来性能问题。因此,对于每一个请求,我们将用一个线程处理数据的接收和发送,同时在数据到达代理服务器时,尽可能快速地把它转发出去。4 服务器的实现4.1 环境创建设计使用Visual C+ 6.0作为编程工具,采用Windows XP系统平台。刚开始时运行VC+ 6.0开发工具,单击菜单“Tools/Options.”,弹出Options对话框,选择Direct

32、ories选项卡,首先在“Show directories for:”下拉菜单中选择Include files,将SDK中头文件的目录添加到:“Directories:”列表中,如图3所示:图3 Include files设置然后在“Show directories for:”下拉菜单中选择Library files,进行同样的设置,如图4所示。在VC主窗口中,执行主菜单“File”/“New”命令,建立一个控制台应用程序类型的工程,工程名为“MiniProxy”;点击“OK”后选择“an application that supports MFC”,之后一直确定,完成项目工程的创建工作。图4

33、 Library files设置4.2 功能实现4.2.1 数据变量定义定义代表http:/类型协议的变量HTTP,定义缓冲区大小变量MAXBUFFERSIZE。运用结构体Str_BasalSocket,里面定义客户端到代理服务器及代理服务器到Server间套接字两个,以及客户端、代理服务器和Server间的连接状态变量两个;Str_ProParam结构体定义Server地址变量,指向结构体Str_BasalSocket的指针,联结Server主机的端口变量和代理服务器到Server连接状态的句柄变量,这个结构体是用来代理服务器与Server主机交换信息。4.2.2 启动代理服务器这里,在运用

34、套接字编程中由于Winsock在被调用时是动态链接库Winsock DLL形式实现的,首先需调用WSAStartup()函数对Winsock DLL进行初始化,它的第一个参数指定要加载的Winsock库的版本,高字节为次版本号,低字节为主版本号;第二个参数是用来返回DLL库的详细信息,是指向WSADATA结构的指针。实现为:WSADATA wsaData;if(:WSAStartup(0x202,&wsaData)!=0)printf(nError in Startup session.n);WSACleanup();return -1;之后,创建一个代理服务器(Proxy)用于网络通信的套接

35、字listen_socket。为了将本地地址附加到所创建的套接字上以便能够有效地标识套接字,我们需用bind函数来完成这一步:SOCKET listen_socket;sockaddr_in local;定义用于保存socket信息的变量。local.sin_family=AF_INET;地址家族用于指定地址格式。local.sin_addr.s_addr=INADDR_ANY;此处将本机IP地址填入此变量。local.sin_port=htons(port);字节顺序转换函数用于将将u_short类型变量port从主机字节顺序转化到TCP/IP网络字节顺序(即:host to nework

36、short)。再用listen_socket=socket(AF_INET,SOCK_STREAM,0)语句打开socket 描述符。if(:bind(listen_socket,(sockaddr *)&local,sizeof(local)!=0)printf(n Error in Binding socket.);WSACleanup();return -3; 绑定完成后,紧接着就将此套接字置入监听以准备接受客户端的连接请求,调用listen函数,:listen(listen_socket,5),最后就可以启动处理线程进行侦听。4.2.3 请求处理过程在这一步设计函数ClientToPr

37、oxy来处理收到客户请求,并将请求合理传送至Server(客户请求的数据服务器)。当客户端有请求发到代理服务器时,侦听中的Proxy就会调用函数accept来响应对主机的连接请求,同时Proxy会启动另一个侦听线程,以准备接收客户端的下一个请求。msg_socket=accept(listen_socket,(struct sockaddr*)&from,&fromlen);此处接收客户端的连接请求,返回客户端的地址和端口。AfxBeginThread(ClientToProxy,pParam);启动另一侦听,用来处理客户端传来的另一个请求。如果此客户端到代理服务器的连接正确,我们就在这一so

38、cket连接上使用revc函数接收数据。SPair.StateClitoProClosed=FALSE;SPair.StateProtoSerClosed=TRUE;SPair.soc_ClitoPro=msg_socket;retval=recv(SPair.soc_ClitoPro,Buffer,sizeof(Buffer),0);如果从套接字接收数据失败,用下面代码给出提示,同时关闭socket句柄,设置客户端到服务器的状态为关闭。if(retval=SOCKET_ERROR) printf(nError Receive); if(SPair.StateClitoProClosed=FA

39、LSE)closesocket(SPair.soc_ClitoPro);SPair.StateClitoProClosed=TRUE;当客户端关闭连接时,这时接收的数据为0,也需要将此时socket状态进行调整:printf(Client Close connectionn);closesocket(SPair.soc_ClitoPro);SPair.StateClitoProClosed=TRUE;下面的一步,需要把这些数据信息传给Server。为此,需要解析出Server的地址,创建函数ReceiveInformation来实现此功能,即声明int ReceiveInformation(

40、char * str, char *address, int * port),其中将实现:char bufMAXBUFFERSIZE, command512, proto128;由于客户端在连接时,都会和代理服务器连接,发出请求,一般为command url(/GET HTTP1.1 = GET / HTTP1.1)形式,定义buf用于存储接收到的请求字符串;command用于保存get,connet,user等命令,这里显然是get;proto保存协议。p=strstr(buf,HTTP);这里strstr 调用用于在字符串buf中寻找http第一次出现的位置(它不会比较结束符NULL),将

41、值赋给指针p。如果分析出请求是HTTP协议类型的,将进行如下处理,首先将字符串协议部份去掉,把地址存于address参数中,端口设为缺省的80,最终返回这些信息,成功解析出Server端的地址信息。至此,启动一个新的子线程,用于处理代理服务器和数据服务器间的数据传输。这个功能将在下面实现。在刚才的处理线程中,如果代理服务器、Server以及客户端、代理服务器端的连接没有关闭,就使用send命令发送请求数据给数据服务器(Server),成功时返回接收的字节数,错误时显示出错信息,并关闭代理服务器到Server的连接套接字,设置连接状态为关闭,直到接下来的处理不出错为止。retval=send(S

42、Pair.soc_ProtoSer,Buffer,Len,0);printf(n send() failed:error%dn,WSAGetLastError();closesocket(SPair.soc_ProtoSer);SPair.StateProtoSerClosed=TRUE;同时代理继续接收客户端的请求,成功时返回接收的字节数,错误时显示出错信息,关闭客户端到代理服务器的套接字,设置连接状态为关闭。直到接下来的处理不出错为止。retval=recv(SPair.soc_ClitoPro,Buffer,sizeof(Buffer),0);如果返回的字节数为零,表示客户端关闭连接,此

43、时也应关闭客户端到代理服务器的套接字,设置连接状态为关闭。否则返回接收信息。Len=retval;#ifdef _DEBUGBufferLen=0;printf(n Received%dbytes,data%sfrom clientn,retval,Buffer);#endif4.2.4 请求响应这一步中,完成ProxyToServer函数的实现。首先要做数据服务器Server主机地址信息的转换,定义一个hostent结构变量*hp来保存。Str_ProParam * pPar=(Str_ProParam*)pParam;char *server_name= localhost;struct

44、sockaddr_in server;struct hostent *hp;server_name = pPar-Address;SOCKET conn_socket;socket_type = SOCK_STREAM;将socket_type类型设定为流式套接字类型,用上面分析出的server地址传给变量server_name,这会在下面的设计中使用。如果server的地址是字母类型的,就使用gethostbyname(server_name)函数返回对应于给定主机名的主机信息(把IP地址串当作一个未知主机名同样处理);否则,应用inet_addr(server_name)把地址串转换为IP

45、地址,再用gethostbyaddr得到hostent结构赋值给hp指针。最后,进行一下不成功的处理:if (hp = NULL ) fprintf(stderr,Client:Cannot resolve address%s:Error %dn,server_name,WSAGetLastError();:SetEvent(pPar-H_StateProToSvr);return 0;有了解析后的地址信息后,下一步,将这些信息拷贝给sockaddr_in结构。memset(&server,0,sizeof(server);memcpy(&(server.sin_addr),hp-h_addr

46、,hp-h_length);server.sin_family = hp-h_addrtype;server.sin_port = htons(port);端口地址转换成网络字节顺序。conn_socket = socket(AF_INET,socket_type,0);打开一个socket,如果打开失败,显示错误信息,关闭代理服务器到服务器的连接状态,if (conn_socket pPair-StateProtoSerClosed=TRUE;return -1;在成功创建套接字的连接后,现在就将接收数据服务器的数据,同样用函数recv来完成,成功时返回接收的字节数,错误时显示出错信息,关闭代理服务器到服务器的套接字,设置连接状态为关闭,如果返回的字节数为零,表示服务端关闭连接,此时也应关闭代理服务器端到服务器Server的套接字的句柄,设置连接状态为关闭。retval = recv(conn_socket,Buffer,sizeof (Buffer),0 );if (retval = SOCKET_ERROR ) fprintf(stderr,recv()failed:error %dn,WSAGetLastError();closesocket(conn_socket);pPar-pPair-StateProtoSerClosed=TRUE;break;Le

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 办公文档 > 其他范文


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号