http代理服务器课程设计报告.doc
- 文档编号:4842288
- 上传时间:2023-05-07
- 格式:DOC
- 页数:18
- 大小:155.50KB
http代理服务器课程设计报告.doc
《http代理服务器课程设计报告.doc》由会员分享,可在线阅读,更多相关《http代理服务器课程设计报告.doc(18页珍藏版)》请在冰点文库上搜索。
目 录
一、绪论 1
二、需求分析 2
三、详细设计 5
四、软件测试 9
五、设计小结 10
参考文献 11
附录 11
一、绪论
本次课设主要要做的是要理解winsock技术网络编程的技术,分析http代理应用程序设计原理,然后选择合适的开发环境用winsock技术来设计http代理的应用程序。
首先先简单的介绍几个相关名词的基本概念:
1.Winsock
Windows下网络编程的规范-WindowsSockets是Windows下得到广泛应用的、开放的、支持多种协议的网络编程接口,现已成为Windows网络编程的事实上的标准。
WindowsSockets规范本意在于提供给应用程序开发者一套简单的API,并让各家网络软件供应商共同遵守。
此外,在一个特定版本Windows的基础上,WindowsSockets也定义了一个二进制接口(ABI),以此来保证应用WindowsSocketsAPI的应用程序能够在任何网络软件供应商的符合WindowsSockets协议的实现上工作。
因此这份规范定义了应用程序开发者能够使用,并且网络软件供应商能够实现的一套库函数调用和相关语义。
2.http代理
www对于每一个上网的人都再熟悉不过了,www连接请求就是采用的http协议,所以我们在浏览网页,下载数据(也可采用ftp协议)是就是用http代理。
它通常绑定在代理服务器的80、3128、8080等端口上。
3.http协议
HTTP协议即超文本传输协议,是Internet上进行信息传输时使用最为广泛的一种非常简单的通信协议。
部分局域网对协议进行了限制,只允许用户通过HTTP协议访问外部网站。
4.http代理服务器
代理服务器英文全称是ProxyServer,其功能就是代理网络用户去取得网络信息。
形象的说:
它是网络信息的中转站。
在一般情况下,我们使用网络浏览器直接去连接其他Internet站点取得网络信息时,须送出Request信号来得到回答,然后对方再把信息以bit方式传送回来。
代理服务器是介于浏览器和Web服务器之间的一台服务器,有了它之后,浏览器不是直接到Web服务器去取回网页而是向代理服务器发出请求,Request信号会先送到代理服务器,由代理服务器来取回浏览器所需要的信息并传送给你的浏览器。
而且,大部分代理服务器都具有缓冲的功能,就好象一个大的Cache,它有很大的存储空间,它不断将新取得数据储存到它本机的存储器上,如果浏览器所请求的数据在它本机的存储器上已经存在而且是最新的,那么它就不重新从Web服务器取数据,而直接将存储器上的数据传送给用户的浏览器,这样就能显著提高浏览速度和效率。
更重要的是:
ProxyServer(代理服务器)是Internet链路级网关所提供的一种重要的安全功能,它的工作主要在开放系统互联(OSI)模型的对话层。
二、需求分析
理解winsock技术网络编程技术,分析HTTP代理应用程序设计原理和程序流程,选择合适的开发环境,参考已有的HTTP程序功能,设计实现HTTP代理功能的应用程序。
1.winsock的理解与分析
这次课设要使用网络编程技术,这就要求掌握winsock的相关知识,因为winsock是Windows下网络编程的规范,是被广泛应用的、开放的、支持多种协议的网络编程接口,要使用winsock编程技术应该了解一些TCP/IP的基础知识,因为WinSock其实就是TCP/IP协议的一种封装,我们可以通过调用WinSock的接口函数来调用TCP/IP的各种功能,例如如果想用TCP/IP协议来发送数据,你就可以使用WinSock的接口函数Send()来调用TCP/IP的发送数据功能,至于具体怎么发送数据,WinSock已经帮你封装好了这种功能,当然这里的TCP/IP协议准确的说来应该是TCP/UDP/IP协议。
Winsocket函数:
Windows 的Socket函数有许多, 我没有做详细介绍, 这里的函数都是简要说明其用途, 这里的主要目的是为了后面的三个应用服务。
函数说明:
WSAStartup函数
初始化Winsock
[声明]
int WSAStarup(WORD wVersionRequested,LPWSADATA lpWSAData);
[参数]
wVersionRequested - 要求使用Winsock的最低版本号
lpWSAData - Winsock的详细资料
[返回值]
当函数成功调用时返回0
失败时返回非0的值
socket函数
用于生成socket(soket Descriptor)
[声明]
SOCKET socket(int af,int type,int protocol);
[参数]
af - 地址家族(通常使用:
AF_INET)
type - socket的种类
SOCK_STREAM :
用于TCP协议
SOCK_DGRAM :
用于UDP协议
protocol - 所使用的协议
[返回值]
当函数成功调用时返回一个新的SOCKET(Socket Descriptor)
失败时返回INVALID_SOCKET.
inet_addr函数
地址转换, 把"A.B.C.D"的IP地址转换为32位长整数
[声明]
unsigned long inet_addr ( const char FAR *cp );
[参数]
cp - 指向IP地址字符串的指针
[返回值]
当函数成功调用时返回用32位整数表示的IP地址
失败时返回INADDR_NONE.
gethostbyname函数
从主机名获取主机信息.
[声明]
struct hostent FAR * gethostbyname ( const char FAR *name );
[参数]
name - 指向主机名字符串的指针
[返回值]
当函数成功调用时返回主机信息
失败时返回NULL(空值)
recv函数
利用Socket进行接受数据.
[声明]
int recv ( SOCKET s , char FAR *buf , int len , int flags );
[参数]
s - 指向用Socket函数生成的Socket Descriptor
buf - 接受数据的缓冲区(数组)的指针
len - 缓冲区的大小
flag - 调用方式(MSG_PEEK 或 MSG_OOB)
[返回值]
成功时返回收到的字节数.
如果连接被中断则返回0
失败时返回 SOCKET_ERROR
sendto函数
发送数据.
[声明]
int sendto ( SOCKET s , const char FAR *buf , int len , int flags , const struct sockaddr FAR *to , int token );
[参数]
s - 指向用Socket函数生成的Socket Descriptor
buf - 接受数据的缓冲区(数组)的指针
len - 缓冲区的大小
flag - 调用方式(MSG_DONTROUTE , MSG_OOB)
to - 指向发送方SOCKET地址的指针
token - 发送方SOCKET地址的大小
[返回值]
成功时返回已经发送的字节数.
失败时返回SOCKET_ERROR
2.有关http代理协议的体系结构
本课设所做的是代理是一种应用层上面的代理,所代理的协议是HTTP,也就是经常见到的Web代理,网络代理就是一个连接客户端(设定需要代理的计算机)和服务器端(需要访问资源的服务器)的桥,以下是网络代理服务的一个典型模型图:
代理服务的运行的流程:
(1).能够接收并解析客户端的请求。
(2).创建到服务器的新连接,并根据转发客户端的请求信息。
(3).接收服务器反馈的信息。
(4).能够发出或解释服务器的响应并将该响应传回给客户端。
三、详细设计
1.程序流程图和设计方案
程序的流程图如下:
实例连接web服务器上
侦听端口,接收客户端浏览器发送来的Web请求信息
解析出Web服务器的地址,创建socket实例
通过创建的Socket传送客户端的Web请求数据包到Web服务器的80端口
接收Web服务器返回页面数据
把接收来的数据传送到客户端
完成,实现了web代理
设计方案:
主要包括三个部分内容:
1).创建一个Web代理类。
2).Web代理服务的类的实例化。
3).通过这个Web代理类的实例实现Web代理服务。
具体方案可以参见下文。
2.选择开发环境,编译源程序
选择visualstudio.net2003开发环境
源程序编译及步骤:
1).创建一个web代理类,命名WebProxy,编辑Proxy.cs文件:
usingSystem;
usingSystem.Net;
usingSystem.Net.Sockets;
usingSystem.Text;
usingSystem.IO;
//以上代码是导入Proxy.cs中要使用到的命名空间
2).用下列构造函数替代默认的构造函数。
下面的代码是在Proxy类中创建一个构造函数。
Proxy类只有一个构造函数,并且这个构造函数只有一个参数,这个参数是Socket对象,它主要用来和客户端进行数据交换,是一个客户Socket。
publicProxy(Socketsocket)
{ this.clientSocket=socket;}
3).创建Proxy类中的Run方法,Run方法是Proxy类中唯一的方法。
其功能是从客户端接收HTTP请求,并传送到Web服务器,然后从Web服务器接收反馈来的数据,并传送到客户端。
为了实现这二个不同方面的数据传送,Run方法中是通过二个Socket实例来实现的。
由于HTTP是TCP/IP参考模型中的应用层协议,它建立于TCP协议之上,所以创建的Socket实例使用的协议类型应该为TCP协议。
下面代码是创建可以传送HTTP请求命令到Web服务器和接收来自Web服务器反馈来信息的Socket实例:
SocketIPsocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
4).另外一个Socket是在代理服务程序侦听端口号,接收挂起的连接请求时候得到的,以此Socket为参数,利用Proxy类中的构造函数,来创建一个Proxy实例的。
此Socket实现从客户端接收HTTP请求信息,并传送数据到客户端。
创建Proxy类的Run方法:
publicvoidRun()
{stringclientmessage="";//存放来自客户端的HTTP请求字符串
stringURL="";//存放解析出地址请求信息
intbytes=ReadMessage(read,refclientSocket,refclientmessage);
if(bytes==0)
{ return;}
intindex1=clientmessage.IndexOf('');
intindex2=clientmessage.IndexOf('',index1+1);
if((index1==-1)||(index2==-1))
{thrownewIOException();}
stringpart1=clientmessage.Substring(index1+1,index2-index1);
intindex3=part1.IndexOf('/',index1+8);
intindex4=part1.IndexOf('',index1+8);
intindex5=index4-index3;
URL=part1.Substring(index1+4,(part1.Length-index5)-8); try{ IPHostEntryIPHost=Dns.Resolve(URL);
Console.WriteLine("远程主机名:
"+IPHost.HostName);
string[]aliases=IPHost.Aliases;
IPAddress[]address=IPHost.AddressList;
Console.WriteLine("Web服务器IP地址:
"+address[0]);
//解析出要访问的服务器地址
IPEndPointipEndpoint=newIPEndPoint(address[0],80);
SocketIPsocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//创建连接Web服务器端的Socket对象
IPsocket.Connect(ipEndpoint);//Socket连Web接服务器
5).在定义Proxy类代码区中加入下列代码:
SocketclientSocket;
Byte[]read=newbyte[1024];
//定义一个空间,存储来自客户端请求数据包
Byte[]Buffer=null;
EncodingASCII=Encoding.ASCII;
//设定编码
Byte[]RecvBytes=newByte[4096];
//定义一个空间,存储Web服务器返回的数据
6).把Proxy类实例化具体语法如下:
publicProxy(Socketsocket);
参数:
socket为一个Scoket实例
Proxyproxy=newProxy(socket);//创建一个Proxy实例:
7).利用Proxy类,实现Web代理:
利用上面创建的Proxy类,实现Web代理程序的具体实现步骤,Proxy类被定义在命名空间WebProxy中。
在Class1.cs源文件的开头导入下列命名空间:
usingSystem;
usingSystem.Net;
usingSystem.Net.Sockets;
usingSystem.Text;
usingSystem.IO;
usingSystem.Threading;
usingWebProxy;//其中命名空间WebProxy是Proxy类所处的位置,具体可以参阅Proxy.cs源文件中命名空间的定义。
8).在Main函数中添加下列代码,下列代码是利用Proxy类,来实现Web代理程序。
constintport=8000;//定义端口号
TcpListenertcplistener=newTcpListener(port);
Console.WriteLine("侦听端口号:
"+port.ToString());
tcplistener.Start();//侦听端口号
while(true)
{ Socketsocket=tcplistener.AcceptSocket();
//并获取传送和接收数据的Scoket实例
Proxyproxy=newProxy(socket);//Proxy类实例化
Threadthread=newThread(newThreadStart(proxy.Run));
//创建线程
thread.Start();//启动线程}
至此简单Web代理程序就算是完成了。
四、软件测试
此代理程序侦听的是8000端口号。
代理程序要通过二台计算机才能够实现。
其中的一台计算机运行Web代理程序,充当Web代理服务器。
另外一台计算机充当客户机,通过Web代理服务器来浏览网页。
在确定Web代理软件运行后,对客户机进行必要的设置:
通过设置IE浏览器的Internet选项设置代理服务器相关的信息,在其中的【地址】文本框中输入代理服务器的IP地址,由于测试的代理服务器的IP地址为"122.93.54.202",所有也输入此IP地址,在【端口】文本框中输入"8000"。
客户端的设置完成之后,在确定IP地址为"122.93.54.202"的这台计算机已经运行代理程序后。
打开客户端的IE浏览器,并输入要浏览的网址,就可以通过Web代理服务器来浏览网页了,运行结果如下图所示:
五、设计小结
虽然代理服务的实现原理相对简单,但具体实现其实还是很繁琐的。
网络代理是一个内容丰富,实现复杂的论题,本课设所做的代理服务软件,无论在实现的协议种类,还是实现的功能,都只能算很小的一部分。
这次课程设计使我感到收获不小,使我对http协议有了更深的了解,促进了对理论知识的消化与吸收,也巩固和完善了本门课程的知识体系结构。
除此之外,对winsock语言的语法结构也有了一定的了解。
通过这次课程设计,使自己在计算机网络方面的知识增加了很多,自己的编程能力也得到了很大的提高,尤其是对网络编程有了一定的了解,能够编写一些简单的网络程序了。
在一周的课设时间里,自己常常跑到图书馆去翻阅各种有关的资料,不断的学习有关方面的知识,在编写源程序代码时又经常上网查阅各种知识,这样自己的知识不断的丰富,自己的编程水平也得到了很大的提高,通过网上一些人的介绍,自己的编程经验也丰富了许多。
参考文献
[1](美)罗//舒赫|译者:
李春洪//李文中//叶保留,《计算机网络》,清华大学出版社
[2]邓亚平,《计算机网络》,电子工业出版社
[3]徐武//王贵柱//孔云龙,《计算机网络工程与实训教程》,电子工业出版社
[4](美)克莱姆|译者:
詹文军//杜晓峰//刘玉鹏,《网络管理技术构架》,人民邮电出版社
[5]
附录
WINDOWS环境下SOCKET基本函数:
(1)WSAStartup函数
intWSAStartup(WORDwVersionRequested,LPWSADATAlpWSAData);
使用Socket的程序在使用Socket之前必须调用WSAStartup函数。
该函数的第一个参数指明程序请求使用的Socket版本,其中高位字节指明副版本、低位字节指明主版本;操作系统利用第二个参数返回请求的Socket的版本信息。
当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。
以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。
该函数执行成功后返回0。
例:
假如一个程序要使用2.1版本的Socket,那么程序代码如下
wVersionRequested=MAKEWORD(2,1);
err=WSAStartup(wVersionRequested,&wsaData);
(2)WSACleanup函数
intWSACleanup(void);
应用程序在完成对请求的Socket库的使用后,要调用WSACleanup函数来解除与Socket库的绑定并且释放Socket库所占用的系统资源。
(3)socket函数
SOCKETsocket(intaf,inttype,intprotocol);
应用程序调用socket函数来创建一个能够进行网络通信的套接字。
第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置PF_INET;第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM、数据报套接字类型为SOCK_DGRAM;第三个参数指定应用程序所使用的通信协议。
该函数如果调用成功就返回新创建的套接字的描述符,如果失败就返回INVALID_SOCKET。
套接字描述符是一个整数类型的值。
每个进程的进程空间里都有一个套接字描述符表,该表中存放着套接字描述符和套接字数据结构的对应关系。
该表中有一个字段存放新创建的套接字的描述符,另一个字段存放套接字数据结构的地址,因此根据套接字描述符就可以找到其对应的套接字数据结构。
每个进程在自己的进程空间里都有一个套接字描述符表但是套接字数据结构都是在操作系统的内核缓冲里。
下面是一个创建流套接字的例子:
structprotoent*ppe;
ppe=getprotobyname("tcp");
SOCKETListenSocket=socket(PF_INET,SOCK_STREAM,ppe->p_proto);
(4)closesocket函数
intclosesocket(SOCKETs);
closesocket函数用来关闭一个描述符为s套接字。
由于每个进程中都有一个套接字描述符表,表中的每个套接字描述符都对应了一个位于操作系统缓冲区中的套接字数据结构,因此有可能有几个套接字描述符指向同一个套接字数据结构。
套接字数据结构中专门有一个字段存放该结构的被引用次数,即有多少个套接字描述符指向该结构。
当调用closesocket函数时,操作系统先检查套接字数据结构中的该字段的值,如果为1,就表明只有一个套接字描述符指向它,因此操作系统就先把s在套接字描述符表中对应的那条表项清除,并且释放s对应的套接字数据结构;如果该字段大于1,那么操作系统仅仅清除s在套接字描述符表中的对应表项,并且把s对应的套接字数据结构的引用次数减1。
closesocket函数如果执行成功就返回0,否则返回SOCKET_ERROR。
(5)send函数
intsend(SOCKETs,constcharFAR*buf,intlen,intflags);
不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。
客户程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。
该函数的第一个参数指定发送端套接字描述符;第二个参数指明一个存放应用程序要发送数据的缓冲区;第三个参数指明实际要发送的数据的字节数;第四个参数一般置0。
这里只描述同步Socket的send函数的执行流程。
当调用该函数时,send先比较待发送数据的长度len和套接字s的发送缓冲区的长度,如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;如果len小于或者等于s的发送缓冲区的长度,那么send先检查协议是否正在发送s的发送缓冲
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- http 代理服务器 课程设计 报告