请教:vc++完成端口实现http代理以及url过滤


要求:
用vc++完成端口实现http代理,且代理要有url过滤功能,及对来自己指定的url请求的页面,要发送给认证服务器进行分析,通过认证,就发个客户端(浏览器)请求的页面,否则给客户端错误提示页面。

请教各位大侠,给个思路或者流程,网上有好多vc++完成端口实现http代理的例子 ,关键的是怎样对一个请求进行解析,得到url,(由于在浏览器地址栏中输入url,发送请求后),在代理端有多次的GET或POST的请求,搞不懂)
流程大体如下(画的确实不好看)


10 个解决方案

#1


本帖最后由 oyljerry 于 2012-11-30 21:54:45 编辑
没人顶啊,自己顶起。

#2


这个要先了解Http协议格式,协议头里带有url

#3


可是在地址栏中输入地址,或单击某个 链接,收到好多GET或POST,那我要解哪个啊,或者都要解析吗,
还有,在单击一个链接时,地址栏中显示的不是这个链接所对应的页面啊,以变量赋值的形式给出,这样链接的URL地址又怎么解析出呢???

#4


都要,你不是做浏览器的代理吗?浏览器连接你的代理服务器,你都得像web服务器一样处理,只是你把最终请求转到请求web服务器罢了

#5


你可以试着处理 GET请求,因为浏览器大部分请求都是GET方式,处理好了GET,再处理其他,至于网络模型什么IOCP都不是最重要的,多线程 select也可以实现

#6


现在很纠结的就是处理浏览器的一堆请求,至于网络模型都没什么问题。是不是用其它语言比如JAVA等什么好处理呢

#7


浏览器连接你,你的代理服务器端会生成一个新的从浏览器到你代理的连接套接字sock1,你从HTTP头里截取出url这个不困难吧?截取好url就把url解析成IP,创建一个socket,命名为sock2,然后用sock2连接对应的服务器,然后发送从sock1读取过来的HTTP数据过去,然后在sock2上接收web服务器回来的数据,然后把数据原样从sock1发送给浏览器,这就是一个简单的代理逻辑

#8


下面是以前我写的一个简单实验代码,只处理了GET,你可以参考下:

#include <stdio.h>
#include <iostream>
#include <winsock2.h>
#include <process.h>
#include "SockInit.h"
using namespace std;

#define MAX_REQUESTLINE_LEN  2048  // IE请求行长度

void __cdecl ServerThreadProc(void *param);
int TCPsend(SOCKET s,const char*buf,int len,int flags);
int TCPrecv(SOCKET s,const char*buf,int len,int flags);
/************************************************

 调试环境:Visual C++6.0 SP6+platform SDK 2003 R2

 程序名称:HTTP proxy Server(HttpProxySvr.cpp)

 功能    :IE通过设置代理方式上网,IE所有请求均
          先发到该代理服务器,代理服务器
          将请求直接转发给webserver, 
  后从webserver读取响应后发回IE
 
**************************************************/

int main()
{
USHORT uPort=9999;   // 通信端口
    
         WORD wVersionRequested;
       WSADATA wsaData;
      int err;
 
      wVersionRequested = MAKEWORD( 2, 2 );
 
      err = WSAStartup( wVersionRequested, &wsaData );
      if ( err != 0 ) 
      {
         return 0;
      }
 
                             
 
   if ( LOBYTE( wsaData.wVersion ) != 2 ||
        HIBYTE( wsaData.wVersion ) != 2 ) 
     {
                                 
    WSACleanup( );
    return  0; 
    }
SOCKET sListen = socket(AF_INET,SOCK_STREAM,0);
if(sListen == INVALID_SOCKET)
{
printf("Failed socket(),error code :%d",WSAGetLastError());
return 0;
}

sockaddr_in sin;
sin.sin_addr.S_un.S_addr = INADDR_ANY;
sin.sin_family =AF_INET;
sin.sin_port = htons(uPort);
 
if(bind(sListen,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)
{
    printf("Failed bind(),error code :%d",WSAGetLastError());
closesocket(sListen);
return 0;
}

int res =listen(sListen,200);

sockaddr_in addrRemote;
int len =sizeof(addrRemote);
while(true)
{
    SOCKET sNew = accept(sListen,(sockaddr*)&addrRemote,&len);
if(sNew == INVALID_SOCKET)
{
printf("Failed accept(),error code :%d",WSAGetLastError());
return 0;
}
    
printf("收到一个IE连接(IP:%s)\n",inet_ntoa(addrRemote.sin_addr));

// 创建一个线程处理该连接 (每客户单线程模式...)
_beginthread(ServerThreadProc,0,(void*)sNew);
}
   
closesocket(sListen);

return 0;
}

void __cdecl ServerThreadProc(void *param)
{
SOCKET sock = (SOCKET)param;   //与浏览器连接的套接口

char request[MAX_REQUESTLINE_LEN];
memset(request,0,MAX_REQUESTLINE_LEN);
int res =recv(sock,request,MAX_REQUESTLINE_LEN,0);  // 接收浏览器(客户端)发来的请求
if(res==0)
{

printf("连接断开\n");

closesocket(sock);
return;
}
shutdown(sock,SD_RECEIVE);
//  打印收到的请求
printf("header length :%d  header: %s\n",res,request);

// 分析请求行(分离出WebServer域名)
    char szAddrName[1024]={0}; //域名
int i =11;
while(request[i]!='/'&&i<res)
{
szAddrName[i-11] = request[i];
i++;

}
szAddrName[i-11]='\0';

printf("WebServer address: %s\n\n",szAddrName);

// 向WebServer提交请求
SOCKADDR_IN   saServer;   
LPHOSTENT     lphostent;     
SOCKET        hsocket;
int   nRet;   

lphostent=gethostbyname(szAddrName); // 通过域名获得目标WebServer的IP 
if(lphostent==NULL)
{
printf("Failed gethostbyname(),error code:%d\n",WSAGetLastError());
return ;   
}

hsocket = socket(AF_INET,SOCK_STREAM,0); 
if(hsocket==INVALID_SOCKET)
{
       printf("Failed socket(),error code:%d\n",WSAGetLastError());
   return ;   
}
saServer.sin_family = AF_INET;   
saServer.sin_port = htons(80);
saServer.sin_addr= *((LPIN_ADDR)*lphostent->h_addr_list);   

nRet = connect(hsocket,(LPSOCKADDR)&saServer,sizeof(SOCKADDR_IN));   
if(nRet==SOCKET_ERROR)   
{   
printf("Failed connect(),error code:%d\n",WSAGetLastError());
closesocket(hsocket);   
return;   


//  向webserver转发IE请求 
nRet = TCPsend(hsocket,request,strlen(request),0);

char   dest[1000];   
nRet=1; 
int senlen=0;
while(nRet>0)   
{   
memset(dest,0,1000);
nRet=recv(hsocket,dest,sizeof(dest)-1,0);  // 从webserver获取数据 
if(nRet==0)   
{
printf("与webserver(%s)的连接关闭\n",szAddrName);

break;
}
else  if(nRet==SOCKET_ERROR )
{
   printf("Failed recv(),error code:%d\n",WSAGetLastError());       
   break;
}
dest[nRet]='\0';

senlen = TCPsend(sock,dest,nRet,0);  //将数据转发给IE浏览器
if(senlen==0)
{
sockaddr_in sin;
int len = sizeof(sin);
if(getpeername(sock,(sockaddr*)&sin,&len)== SOCKET_ERROR)
{
printf("Failed getpeername(),error code:%d\n",WSAGetLastError());
break;
}
            printf("与浏览器(%s)的一个连接关闭...\n",inet_ntoa(sin.sin_addr));
break;
}
else if(senlen==SOCKET_ERROR)
{
   printf("Failed send(),error code:%d\n",WSAGetLastError());       
   break;
}

// printf("%s\n",dest);

} // end of while(nRet>0)   


closesocket(sock);
closesocket(hsocket);

}

int TCPsend(SOCKET s,const char*buf,int len,int flags)
{
int n=0,sendCount=0;
int length =len;
if(buf==NULL)
return 0;
while(length>0)
{
n=send(s,buf+sendCount,length,flags); //发送数据,
if(n==SOCKET_ERROR)//网络出现异常
{
printf("Failed send(),error code:%d\n",WSAGetLastError());
break;

}
length-=n;
sendCount+=n; 
}

return sendCount; // 返回已发送的字节数
}

int TCPrecv(SOCKET s,char *buf,int len,int flags)
{

int nRev=0,recvCount=0;
int length =len;

if(buf==NULL)
return 0;

// 循环接收数据
while(length>0)
{
nRev =recv(s,buf+recvCount,length,flags);
if(nRev==SOCKET_ERROR)//网络出现异常
{
printf("Failed recv(),error code:%d\n",WSAGetLastError());
break;
}
length-=nRev;
recvCount+=nRev;
}

return recvCount; //返回接收到的字节数
}

#9


谢谢,解析URL是我理解错 了,已经搞定 了,现在有一个新问题,我是用完成端口做的, 需要收到完成的HTTP请求包,比如有的请求包分两次发过 来,我需要将包的全部数据 接收到,但发现包的顺序是乱的,没法重新组包啊,已经郁闷了好几天了,就一个服务线程也不行,给个思路吧。

#10


从请求出发记录域名 然后通过认证服务器认证,如果合法让其访问web服务器。。。
智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
China Scenic Area
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告