本帖最后由 grewav_vip 于 2012-11-28 22:48:03 编辑

解决方案 »

  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服务器