优秀的毕业设计论文网
计算机 JAVA 电子信息 单片机 机械机电 模具 土木工程 建筑结构 论文
热门搜索词:网络 ASP.NET 汽车 电气 数控 PLC

055_简易代理服务器

以下是资料介绍,如需要完整的请充值下载.
1.无需注册登录,支付后按照提示操作即可获取该资料.
2.资料以网页介绍的为准,下载后不会有水印.资料仅供学习参考之用.
  
资料介绍:

1 引言
1.1 课题背景
普通的因特网访问是一种典型的客户机与服务器结构,而代理服务器将运行于客户机与服务器之间,它作为Internet/Intranet上常用的一种服务器,通常配置在Intranet连接Internet的出口处,主要实现代理传输服务。可以这样认为,代理是双向的。即对于内部网上的用户来说,代理服务器可看作是一个外部网的代理;对于外部网络来说,代理服务器可以看作一个要访问外部网的客户。正是由于代理服务器的这种控制方式,可以使用它提高客户访问外网的效率、节省网络带宽,增强网络安全性以及减少网络投资等。代理服务器从提出到现在,不断的经历着内容更进和技术的革新,各种代理服务器产品更是层出不穷。不难看出,代理服务器在我们信息时代的生活中扮演着越来越重要的作用。

【www.think58.com计算机毕业论文网】

[资料来源:www.THINK58.com]


1.2 本课题研究的意义
随着Internet与Intranet的飞速发展,作为连接Internet与Intranet的桥梁,代理服务器在实际应用中发挥着极其重要的作用。它可用于多个目的,最基本的功能是连接;此外还包括安全性、缓存、内容过滤、访问控制管理等功能。在代理服务器的众多功能中,安全性是一个突出且敏感的功能。绝大多数企业、部门在使用代理服务器的时候,都会考虑这个问题,把它作为选购代理服务器产品的重要依据。目前市场上流行的代理服务器,像Microsoft Proxy Server、Netscape Proxy Server、Win Gate等国外的产品,功能和性能等方面都还不错,我们正好可以通过借鉴它们产品的优点,开发一个具有自主产权的代理服务器产品。而且从保证安全性的角度出发,我们也很有必要开发一个自己的代理服务器。除了上面的因素外,通过一个简单的代理程序的开发,我们能从实现过程中学习到网络通信和网络编程的基础知识,加深理解和掌握我们所使用的开发语言。另外,我们也能从中学习到正确的程序开发流程,积累程序开发经验,为以后更深课题的研究打好基础。
1.3 本课题的研究方法
此代理服务器系统将是建立在Windows NT平台上的网络应用程序设计。由于需要服务器为其他许多称为客户的主机提供服务,而客户主机又可以随时打开和关闭,在选择网络应用程序体系结构时就采用支持这些特点的客户机/服务器结构。还将运用Windows下网络编程的标准接口WinSock ,因为它允许两个或多个应用程序在相同机器上,或者是通过网络相互交流,它是真正协议无关的接口。为了便于直接使用Windows提供的网络编程接口,我们使用Microsoft Visual C++ 6.0作为开发工具,利用MFC类库中提供的两个Socket类CAsyncSocket和Csocket。使用这两个Socket类,我们可以运用面向对象的方法来进行Socket编程,而且它们还分别在较低和较高层次上封装了Windows Sockets API,为程序员开发Socket程序提供了便利。

copyright think58

[资料来源:http://THINK58.com]


2 理论基础
2.1 代理服务器
代理服务器的英文全称是Proxy Server,其功能就是代理网络用户去取得网络信息。形象的说:它是网络信息的中转站。很多人不知不觉中就在用代理服务器共享上网,比如sygate,wingate,isa,ccproxy,NT系统自带的网络共享等,它们可以提供企业级的文件缓存,复制和地址过滤等服务。在一般情况下,我们使用网络浏览器直接去连接其他Internet站点取得网络信息时,须送出Request信号来得到回答,然后对方再把信息以bit方式传送回来。代理服务器是介于浏览器和Web服务器之间的一台服务器,有了它之后,浏览器不是直接到Web服务器去取回网页而是向代理服务器发出请求, Request信号会先送到代理服务器,由代理服务器来取回浏览器所需要的信息并传送给你的浏览器。而且,大部分代理服务器都具有缓冲的功能,就好像一个大的Cache,它有很大的存储空间,它不断将新取得数据储存到它本机的存储器上,如果浏览器所请求的数据在它本机的存储器上已经存在而且是最新的,那么它就不重新从Web服务器取数据,而直接将存储器上的数据传送给用户的浏览器,这样就能显著提高浏览速度和效率。更重要的是:Proxy Server (代理服务器)是 Internet链路级网关所提供的一种重要的安全功能,它的工作主要在开放系统互联(OSI)模型的对话层。主要的功能有:

[来源:http://www.think58.com]


1、连接Internet与Intranet充当防火墙:因为所有内部网的用户通过代理服务器访问外界时,只映射为一个IP地址,所以外界不能直接访问到内部网;同时可以设置IP地址过滤,限制内部网对外部的访问权限;另外,两个没有互联的内部网,也可以通过第三方的代理服务器进行互联来交换信息。
2、节省IP开销:前面所讲,所有用户对外只占用一个IP,所以不必租用过多的IP地址,降低网络的维护成本。这样,局域局内没有与外网相连的众多机器就可以通过内网的一台代理服务器连接到外网,大大减少费用。当然也有它不利的一面,如许多网络黑客通过这种方法隐藏自己的真实IP地址,而逃过监视。
3、提高访问速度:本身带宽较小,通过带宽较大的proxy与目标主机连接。而且通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,从而达到提高访问速度的目的。
4、防止攻击:隐藏自己的真实地址信息,还可隐藏自己的IP,防止被黑客攻击。通过分析指定IP地址,可以查询到网络用户的目前所在地。例如,大家在一些论坛上看到,论坛中明确标出了发帖用户目前所在地,这就是根据论坛会员登录时的IP地址解析的。还有平日里我们最为常用的显IP版QQ,在“发送消息”窗口中,可以查看对方的IP及解析出的地理位置。而当我们使用相应协议的代理服务器后,就可以达到隐藏自己当前所在地地址的目的了。 copyright think58 [资料来源:www.THINK58.com]
5、突破IP访问限制:使用它可以访问一些有IP禁止访问的服务器,因为封锁只禁止了你和目标服务器的连接,但并没有禁止你与代理服务器的连接 以及代理服务器与目标服务器的连接。
代理服务器有许多种,大体来说有HTTP,FTP,SOCKS代理三种,其中又分透明代理和不透明代理。其中透明代理一般是网关,是硬件,所以不讨论透明代理。当机器通过代理服务器上网时。通讯是分两次的,先是机器和代理服务器通讯,再是代理服务器和目的地址通讯。机器和代理服务器通讯时,目的IP是代理服务器的IP。代理服务器和目的地址通讯时,源IP是代理服务器的IP,当然外部的数据也是一样的。在内网中,出现的IP数据,全是内网和代理服务器的IP。因此,从IP包头是看不出任何与外面通讯的信息的。只有从数据中才能看到。
2.2 目前的代理服务技术
代理服务技术是在一台PC机上安装一套代理软件,主要用于用户对Internet资源的访问。
ICS即Internet连接共享(Internet Connection Sharing)的英文简称,是Windows系统针对家庭网络或小型的Intranet网络提供的一种Internet连接共享服务。它实际上相当于一种网络地址转换器,所谓网络地址转换器就是当数据包向前传递的过程中,可以转换数据包中的IP地址和TCP/UCP端口等地址信息。有了网络地址转换器,家庭网络或小型的办公网络中的电脑就可以使用私有地址,并且通过网络地址转换器将私有地址转换成ISP分配的单一的公用IP地址从而实现对Internet的连接。ICS方式也称之为Internet转换连接。例如有软件:Wingate,Winproxy等。 think58好,好think58

[资料来源:http://www.THINK58.com]


NAT即网络地址转换(Network Address Translator),从广义上讲,ICS也是使用了一种NAT技术,不过我们这里讨论的NAT是指将运行Windows 2000 Server的计算机作为IP路由器,通过它在局域网和Internet主机间转发数据包从而实现Internet的共享。NAT方式也称之为Internet的路由连接。网络地址转换NAT通过将专用内部地址转换为公共外部地址,对外隐藏了内部管理的IP地址。这样,通过在内部使用非注册的IP地址,并将它们转换为一小部分外部注册的IP 地址,从而减少了IP 地址注册的费用。同时,这也隐藏了内部网络结构,从而降低了内部网络受到攻击的风险。例如有软件:WinRoute,Sygate。
2.3 Socket 面向连接的编程模型
代理服务器既然是双向的客户机/服务器模型,它工作时通常有一个公共的规则需要遵守,通信双方需要共同遵守这个规则才能保证通信的有效进行,如需要量传输大量语音信息时须采用一种无须建立连接的传输方式,在这种方式下,数据可以以较快的速度传输。而当需要确保数据准确无误地到达时,则应采用面向连接的传输方式。代理服务器就要求采用这种方式,在这种模型下,当服务器程序的套接字创建并初始化完毕时,它先进入休眠状态,直到有客户机向该服务器程序提出连接请求。这时,服务器程序被“唤醒”,并开始响应客户机提出的连接请求。这时双方协商数据由谁来接收和由谁来发送,在数据传输完毕时,双方再分别关闭连接,释放因创建套接字而占用的资源,面向连接的编程模型示意图如下: [资料来源:THINK58.com]
图1面向连接的编程模型
上面的示意图向我们显示了面向连接的服务器程序和客户程序的创建与结束过程。首先服务器端创建监听套接字,并为它关联一个本地地址(指定IP地址和端口号),然后进入监听状态准备接收客户端的连接请求。为了接受客户端的连接请求,服务器必须调用accept函数。
客户端创建套接字后即可调用connect函数去试图连接服务器监听套接字。当服务器端的accept函数返回后,connect函数也返回。此时客户端使用socket函数创建的套接字,服务器端使用accept函数创建的套接字,双方就可以通信了。
当数据完成交换后,客户程序和服务器程序都会分别关闭创建的套接字句柄以完成双方的对话,至此程序服务结束。
2.4 Winsock库
Winsock是Windows下网络编程的标准接口,它允许两个或多个应用程序在相同机器上,或者是通过网络相互交流。Winsock库的装入时是对Winsock DLL版本的进行选择,每个Winsock应用程序都必须加载与之相应的版本的Winsock DLL。如果没有加载,将返回SOCKET_ERROR,加载的函数是WSAStartup,其定义如下:
int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);
它的第一个参数就是要加载的库版本,第二个参数是用来返回DLL库的详细信息的。

内容来自think58 [来源:http://www.think58.com]


2.4.1 winsock的寻址方式
因为Winsock要兼容多个协议,所以必须使用通用的寻址方式。TCP/IP使用地址和端口号来指定一个地址,但是其它协议也许采用不同的形式。如果Winsock强迫使用特定的寻址方式,添加其他协议就不大可能了。在Winsock中,应用程序员通过SOCKADDR_IN结构来指定IP地址和端口号。定义如下:
Struct sockaddr_in{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
har sin_zero[8];
};
应用程序可以使用inet_addr函数将一个小数点分隔的十进制IP地址字符串转化成由32位二进制数表示的IP地址。inet_ntoa函数将一个网络字节顺序的32位IP地址转化字符串。注意:inet_addr返回的32位二进制数是用网络顺序存储的。
2.4.2 字节顺序
字节顺序是长度跨越多个字节的数据被存储的顺序,分为小尾顺序和大尾顺序,TCP/IP统一规定使用大尾顺序方式传输数据,即网络字节顺序,它的字节顺序是最重要的字节首先存储。Winsock提供了一些函数来处理本地机器的字节顺序和网络字节顺序的转换,htons将主机字节顺序转化到TCP/IP网络字节顺序,ntohs将网络字节顺序转化到主机字节顺序,此外还有htonl和ntohl。这API数据都是平台无关的。使用它们可以保证程序正确运行在所有机器上。

think58

[资料来源:http://think58.com]


2.5 系统基本套接字调用
2.5.1 创建和关闭套接字-socket()和closesocket()
应用程序在使用套接字前,首先必须拥有一个套接字,系统调用socket()向应用程序提供创建套接字的手段,如果成功将返回套接字句柄,如果创建失败,返回INVALID_SOCKET(即-1)。当不使用此套接字时,应该用closesocket函数关闭套接字,如果没有错误发生,函数返回0,否则返回SOCKET_ERROR。
2.5.2 指定本地地址-bind()
当一个套接字用socket()创建后,存在一个名字空间(地址族),但它没有被命名。bind()将套接字地址(包括本地主机地址和本地端口地址)与所创建的套接字号联系起来,即将名字赋予套接字,以便能够有效地标识套接字。它用在没有建立连接的套接字上,如果没有错误发生,bind()返回0。否则返回值SOCKET_ERROR。当然,客户端程序也可以在不显示绑定地址和端口号的情况下发送数据或者连接。这时系统会默认地为套接字绑定一个本地端口值。注意:地址在建立套接字通信过程中起着重要作用,程序使用中通常靠填充sockaddr_in结构来绑定套接字到本地地址。绑定到套接字上的本地名称包括主机地址、协议号和端口号3部分。
2.5.3 设置监听状态-listen()
Listen函数设置套接字进入监听状态。为了接受连接,首先使用socket函数创建套接字,然后使用bind函数将它绑定到本地地址,再用listen函数为到达的连接指定backlog,最后使用accept函数接受请求的连接。Listen函数仅应用在支持连接的套接字上,如SOCK_STREAM类型。函数执行成功后,套接字将进入被动模式,到来的连接会通知要排队并等候接受处理。在同一时间处理多个连接请求的服务器通常使用listen函数,如果一个连接请求到达并且排队也满,客户端将接收错误。 think58.com [资料来源:THINK58.com]
2.5.4 建立套接字连接-connect()和accept()
这两个系统调用用于完成一个完整相关的建立,用于客户机与网络中的服务器建立连接时,用connect()这个调用连接将请求发到侦听方。之后,服务端就会调用accept(),而在调用accept ()的参数前应该先调用过listen(),Accept函数定义如下:
SOCKET accept(SOCKET soc, struct sockaddr * addr, int * addrlen);
2.5.5 收发数据-send()和recv()
对流套接字来说,一般使用send和recv函数来收发数据。
Send函数在一个连接的套接字上发送缓冲区内的数据,返回发送数据的实际字节数。Recv函数从对方接收数据,并将其存储到指定的缓冲区。Flags参数在这两函数中通常设为0。
3 设计方案
3.1 基本函数设计
我们根据上面讨论的代理服务器内容容易画出代理服务器的简单流程模型:
图2 代理服务器的流程
从图中看出,我们需要设计的基本功能函数为ClientToProxy和ProxyToServer。其中,ClientToProxy用于实现收取Client数据请求并传给Server;ProxyToServer用于接收Server的数据、传给请求Client。在处理数据请求的过程中,我们必须知道Server的地址,这是非常重要的。这需要设计一个函数来解析地址,设计过程中用ReceiveInformation函数来实现。
[资料来源:http://think58.com]

另外,任何Windows Socket函数对IP地址和端口号的引用和传送给Windows Sockets函数的IP地址和端口号均是按照网络顺序组织的,这也包括了sockaddr_in结构这一数据类型中的IP地址域和端口域(但不包括sin_family域)。考虑到一个应用程序通常用“时间”服务对应的端口来和服务器连接,而服务器提供某种机制来通知用户使用另一端口,因此gethostbyname()函数返回的端口号已经是网络顺序了,可以直接用来组成一个地址,而不需要进行转换。如果用户输入一个数,而且指定使用这一端口号,则应用程序必须在使用它建立地址以前,把它从主机顺序转换网络顺序(使用htons()函数)。相应地,应用程序希望显示包含于某一地址中的端口号,这一端口号就必须在被显示前从网络顺序转换到主机顺序(ntohs)。
3.2 多线程流程
由于代理服务器和大多数服务器一样,如果要处理多个请求,它应该使用多线程。其基本规划如下:
1. 等待来自客户(Web浏览器)的请求
2. 启动一个新的线程,以处理客户连接请求
3. 读取浏览器请求的第一行(该行内容包含了请求的目标URL)
4. 分析请求的第一行内容,得到目标服务器的地址和端口
5. 打开一个通向目标服务器(或下一个代理服务器,如合适的话)的Socket 内容来自think58 [版权所有:http://think58.com]
6. 把请求的第一行发送到输出Socket
7. 把请求的剩余部分发送到输出Socket
8. 把目标Web服务器返回的数据发送给发出请求的浏览器
当然,如果考虑细节的话,情况会更复杂一些。实际上,这里主要有两个问题要考虑:第一,从Socket按行读取数据最适合进一步处理,但这会产生性能瓶颈;第二,两个Socket之间的连接必需高效。有几种方法可以实现这两个目标,但每一种方法都有各自的代价。例如,如果要在数据进入的时候进行过滤,这些数据最好按行读取;然而,大多数时候,当数据到达代理服务器时,立即把它转发出去更适合高效这一要求。另外,数据的发送和接收也可以使用多个独立的线程,但大量地创建和拆除线程也会带来性能问题。因此,对于每一个请求,我们将用一个线程处理数据的接收和发送,同时在数据到达代理服务器时,尽可能快速地把它转发出去。
4 服务器的实现
4.1 环境创建
设计使用Visual C++ 6.0作为编程工具,采用Windows XP系统平台。刚开始时运行VC++ 6.0开发工具,单击菜单“Tools/Options...”,弹出Options对话框,选择Directories选项卡,首先在“Show directories for:”下拉菜单中选择Include files,将SDK中头文件的目录添加到:“Directories:”列 本文来自think58

[来源:http://think58.com]


表中,如图3所示:
图3 Include files设置
然后在“Show directories for:”下拉菜单中选择Library files,进行同样的设置,如图4所示。在VC主窗口中,执行主菜单“File”/“New”命令,建立一个控制台应用程序类型的工程,工程名为“MiniProxy”;点击“OK”后选择“an application that supports MFC”,之后一直确定,完成项目工程的创建工作。
图4 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 启动代理服务器
这里,在运用套接字编程中由于Winsock在被调用时是动态链接库Winsock DLL形式实现的,首先需调用WSAStartup()函数对Winsock DLL进行初始化,它的第一个参数指定要加载的Winsock库的版本,高字节为次版本号,低字节为主版本号;第二个参数是用来返回DLL库的详细信息,是指向WSADATA结构的指针。实现为: think58
[版权所有:http://think58.com]

WSADATA wsaData;
if(::WSAStartup(0x202,&wsaData)!=0)
{
printf("\nError in Startup session.\n");
WSACleanup();
return -1;
}
之后,创建一个代理服务器(Proxy)用于网络通信的套接字listen_socket。为了将本地地址附加到所创建的套接字上以便能够有效地标识套接字,我们需用bind函数来完成这一步:
SOCKET listen_socket;