VC++ 高级黑客编程之 第三节 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("初始化失败\n"); 
       		return 1; 
   	} 
   									//创建socket端口 
   	MainSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
   	if(MainSocket == SOCKET_ERROR) 
   	{ 
       		printf("端口创建错误\n");
	   	return 1;
   	} 
   	Host.sin_family = AF_INET; 
   	Host.sin_port = htons(8080); 
   	Host.sin_addr.s_addr = inet_addr("127.0.0.1"); 
   	printf("正在工作\n"); 
   										//绑定socket
   	if(bind(MainSocket,(SOCKADDR *)&Host,sizeof(Host)) != 0) 
   	{ 
       		printf("绑定错误\n");
   	} 
   	i = 0; 
   										//监听 
   	if(listen(MainSocket,5) == SOCKET_ERROR) 
   	{ 
       		printf("监听错误\n"); 
   	} 
   	AddLen = sizeof(Client); 

   								//连接新的客户 
   	i = 0; 
   	for(;;) 
   	{ 
       		ClientSocket = accept(MainSocket,(SOCKADDR *)&Client,&AddLen); 
       		if(ClientSocket == SOCKET_ERROR) 
       		{ 
           		printf("接受客户请求错误!\n"); 
       		} 
       		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("错误\n"); 
       		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("端口创建错误\n"); 
       		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\n",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("服务器名字太长\n"); 
       			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("取得主机信息错误\n"); 
           	printf("%s\n",ServerName); 
           	return -1; 
       } 
       	memcpy(&pServer->sin_addr,pHost->h_addr_list[0],sizeof(pServer->sin_addr)); 
   } 
    
   return 0; 
} 

posted on 2013-03-21 15:45  AI_JJ  阅读(133)  评论(0)    收藏  举报

导航