VC兑现HTTP代理服务器
在编写一个通过P2P允许内网访问另一内网的web Server时,涉及截取浏览器发出的请求,对请求进行分析,如果是某个特定的HOST时,则进行转向。发起P2P请求到另一内网的某个主机。
经过实验性编程,终于解决了该问题。
1、 思路当前流行的浏览器的系统选项中有一个参数,即“通过代理服务器连接”,经过编程测试,当局域网中一台工作站指定了该属性,再发出Internet请求时,请求数据将发送到所指定的代理服务器上,
以下为请求数据包示例:
GET http://www.baidu.com/ HTTP/1.1
Accept: */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT)
Host: www.baidu.com
Proxy-Connection: Keep-Alive
其中第一行为目标URL及相关方法、协议,“Host”行指定了目标主机的地址。由此知道了代理服务的过程:接收被代理端的请求、连接真正的主机、接收主机返回的数据、将接收数据发送到被代理端。为此可编写一个简单的程序,完成上述网络通信重定向问题。
用VC设计时,创建一个监听线程来接受浏览器发起的连接。编程时应解决的一个重要问题是多重连接处理问题,为了加快代理服务的速度和被代理端的响应速度,与web 服务端连接的socket采用异步方式来进行连接。通信的衔接过程如下所示:
1、浏览器发起socket连接到代理服务器
2、代理服务器监听线程接受浏览器的连接,创建一个新线程,同时将接受的socket与新线程绑定到一起。
3、新线程启动时,对该socket设置消息模式(我采用的是一个继承CAsyncSocket的类),并设置FD_CLOSE | FD_READ.同时,新线程向主线程发送一个登陆消息,把自己的线程ID报告给主线程(把线程ID报告给主线程,是因为在主线程有主界面,并设定一个定时器,通过主界面的定时器,向各个线程发送定时器消息,避免对每个线程都开启定时器,减少资源消耗) 4、在OnRecieve函数中读取浏览器发起的请求信息,进行分析,分析出目标主机和端口,根据http请求方式不同,作出不同的动作。目前只实现了http中GET和POST方法,同时只实现http1.1版本。处理POST方法时,需要获得消息的长度,即Content-Length的值,来判断POST的消息是否传输完毕。
5、当得到目的主机和端口时,新建socket连接到web server.这里有点需要注意,即浏览器可能会通过一个SOCKET给代理服务器发送不同的请求主机地址。所以,对这个socket我建立了一个socket队列,该队列的每个socket连接到不同主机。我是采用CAsyncSocket的继承类来作为socket队列的成员,并将该线程绑定的socket作为CAsyncSocket继承类的成员,同时通过WSAAsyncSelect来设置异步消息方式FD_READ | FD_CLOSE。对每个请求分析其目标地址,如果该地址之前连接过,目前连接还没断开,则继续用原来的连接。与web server的连接是采用异步方式,设定一个超时值,当连接超时时,代理服务器发送超时响应,并断开与浏览器的连接。连接成功后,就发送请求。剑道独尊
6、当接受到服务器的响应消息后,触发FD_READ消息,读取信息,并把消息通过socket成员发送到客户端浏览器这就是http代理服务器的服务过程。
后记由于这种设计思路仅仅在被代理端和远程主机之间增加了一个重定向功能,被代理端原有的缓存技术等特点均保留,因此效率较高。 通过该方式的实现,目前已经很适用项目的目的