黑客编程教程(十五)HTTP代理

#include <stdio.h>  
#include <winsock2.h> 

#define  MAXBUFLEN  20480 

#define  HTTPADDLEN 50 

#define  TIMEWAIT   2000 

#pragma comment(lib,"ws2_32.lib")

SOCKET   Global[1000]; 

 

DWORD WINAPI  Proxy( LPVOID pSocket); 

int   ParseHttpRequest(char * SourceBuf,int DataLen,void * ServerAddr); 

 

 

int main(int argc,char * argv[]) 

{ 

    SOCKET  MainSocket,ClientSocket; 

    struct  sockaddr_in Host,Client; 

    WSADATA WsaData; 

    int  AddLen,i; 

 

    //初始化 

   

    if(WSAStartup(MAKEWORD(2,2),&WsaData) < 0) 

    { 

        printf("初始化失败
"); 

        return 1; 

    } 

    //创建socket端口 

    MainSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 

    if(MainSocket == SOCKET_ERROR) 

    { 

        printf("端口创建错误
");

   return 1;

    } 

    Host.sin_family = AF_INET; 

    Host.sin_port = htons(8080); 

    Host.sin_addr.s_addr = inet_addr("127.0.0.1"); 

    printf("正在工作
"); 

    //绑定socket

    if(bind(MainSocket,(SOCKADDR *)&Host,sizeof(Host)) != 0) 

    { 

        printf("绑定错误
");

    } 

    i = 0; 

    //监听 

    if(listen(MainSocket,5) == SOCKET_ERROR) 

    { 

        printf("监听错误
"); 

    } 

    AddLen = sizeof(Client); 

 

    //连接新的客户 

    i = 0; 

    for(;;) 

    { 

        ClientSocket = accept(MainSocket,(SOCKADDR *)&Client,&AddLen); 

        if(ClientSocket == SOCKET_ERROR) 

        { 

            printf("接受客户请求错误!
"); 

        } 

        printf("."); 

        i ++ ; 

        if( i >= 1000) 

            i = 0; 

        Global[i] = ClientSocket; 

 

        //对于每一个客户启动不同的线程程进行控制 

        //这个地方在使用ClientSocket的时候,要不要保证在某一时刻内只能有一个进程使用?     

 

   CreateThread(NULL,0,Proxy,(LPVOID)Global[i],0,NULL);

 

        

    } 

 

    

return 0;

} 

DWORD WINAPI Proxy( LPVOID pSocket) 

{ 

    SOCKET ClientSocket; 

    char  ReceiveBuf[MAXBUFLEN]; 

    int  DataLen; 

    struct sockaddr_in  ServerAddr; 

    SOCKET  ProxySocket; 

    int i = 0; 

    int time = TIMEWAIT; 

 

    //得到参数中的端口号信息 

    ClientSocket = (SOCKET)pSocket; 

//接受第一次请求信息 

    memset(ReceiveBuf,0,MAXBUFLEN); 

    DataLen = recv(ClientSocket,ReceiveBuf,MAXBUFLEN,0); 

 

    if(DataLen == SOCKET_ERROR) 

    { 

        printf("错误
"); 

        closesocket(ClientSocket); 

       return 0;

    } 

    if(DataLen == 0) 

    { 

        closesocket(ClientSocket); 

       return 0;

    }     

    //处理请求信息,分离出服务器地址 

    if( ParseHttpRequest(ReceiveBuf,DataLen,(void *)&ServerAddr) < 0) 

    { 

        closesocket(ClientSocket); 

        goto error; 

    } 

    //创建新的socket用来和服务器进行连接 

    ProxySocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 

    //设置超时时间 

    setsockopt(ProxySocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&time,sizeof(time)); 

    if(ProxySocket == SOCKET_ERROR) 

    { 

        printf("端口创建错误
"); 

        return 0;

    } 

    if(connect(ProxySocket,(SOCKADDR *)&ServerAddr,sizeof(ServerAddr)) == SOCKET_ERROR) 

    { 

        //printf("连接服务器错误"); 

        goto error; 

    } 

    //开始进行数据传输处理 

    //发送到服务器端 

    if(send(ProxySocket,ReceiveBuf,DataLen,0) == SOCKET_ERROR) 

    { 

        //printf("数据发送错误"); 

        goto error; 

 

    } 

        //从服务器端接受数据 

    while(DataLen > 0) 

    { 

        memset(ReceiveBuf,0,MAXBUFLEN); 

    

        if((DataLen = recv(ProxySocket,ReceiveBuf,MAXBUFLEN,0)) <= 0) 

        { 

            //    printf("数据接受错误"); 

            break; 

            

        } 

              else 

            //发送到客户端 

            if(send(ClientSocket,ReceiveBuf,DataLen,0) < 0) 

            { 

                //    printf("数据发送错误"); 

                    break; 

            } 

        

    } 

    

error: 

    closesocket(ClientSocket); 

    closesocket(ProxySocket); 

 

    return 0; 

 

} 

int  ParseHttpRequest(char * SourceBuf,int DataLen,void * ServerAddr) 

{ 

 

    char * HttpHead = "http://"; 

    char * FirstLocation = NULL; 

    char * LastLocation = NULL; 

    char * PortLocation = NULL; 

    char  ServerName[HTTPADDLEN]; 

    char  PortString[10]; 

    int   NameLen; 

    struct hostent * pHost; 

    struct sockaddr_in * pServer = (struct sockaddr_in *)ServerAddr; 

    //取得http://的位置 

    FirstLocation = strstr(SourceBuf,HttpHead) + strlen(HttpHead); 

    //取得/的位置 

    printf("%s
",FirstLocation);

    LastLocation=strstr(FirstLocation,"/"); 

 

    //得到http://和/之间的服务器的名称 

    

    memset(ServerName,0,HTTPADDLEN); 

    memcpy(ServerName,FirstLocation,LastLocation - FirstLocation); 

 

    //有些情况下,请求的地址中带有端口号格式为“:+ 端口号”; 

    //取得 :的位置 

    PortLocation = strstr(ServerName,":"); 

 

    

    //填充server结构 

    pServer->sin_family = AF_INET; 

    //在url中制定了服务器端口 

    if(PortLocation != NULL) 

    { 

        NameLen = PortLocation - ServerName -1; 

        memset(PortString,0,10); 

        memcpy(PortString,PortLocation + 1,NameLen); 

        pServer->sin_port = htons((u_short)atoi(PortString)); 

        *PortLocation = 0;     

    } 

    else//在url中,没有制定服务器端口 

    { 

        pServer->sin_port=htons(80); 

    } 

 

    if(NameLen > HTTPADDLEN) 

    { 

        printf("服务器名字太长
"); 

        return -1; 

    } 

    

    //得到服务器信息 

    //如果地址信息是以IP地址(192.168.0.1)的形式出现的 

    if(ServerName[0] >= '0' && ServerName[0] <= '9') 

    { 

        

        pServer->sin_addr.s_addr = inet_addr(ServerName); 

    } 

    //以域名的形式出现的(www.sina.com.cn) 

    else 

    { 

        pHost = (struct hostent *)gethostbyname(ServerName); 

        if(!pHost) 

        { 

            printf("取得主机信息错误
"); 

            printf("%s
",ServerName); 

            return -1; 

       } 

        memcpy(&pServer->sin_addr,pHost->h_addr_list[0],sizeof(pServer->sin_addr)); 

   } 

    

   return 0; 

} 

 
原文地址:https://www.cnblogs.com/rinack/p/3195668.html