⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 http代理服务器.c

📁 httpproxy,采用vc++实现的
💻 C
字号:
#include "HTTPPROXY.h"
#define FD_NOEVENT 0
//
#define BACKUP 100  //最大连接数
#define MAXDATALEN 65535
int HttpListenPort; //http代理服务器监听端口
SOCKET HttpListenSock;  //http代理服务器监听socket
//
typedef struct _CLIENTINFO{  //保存客户端信息结构体
SOCKET clientsock;           //客户端socket
SOCKET udpsock;
sockaddr_in clientsock_addr; //客户端地址
}CLIENTINFO,*LPCLIENTINFO;
CLIENTINFO HttpClientInfo;
//
typedef struct _SOCKINFO{   //socket信息结构体
SOCKET sourcesock;
SOCKET destsock;
}SOCKINFO,*LPSOCKINFO;
SOCKINFO httpsockinfo;
//
extern long GetSocketEventId(SOCKET remotesock);
extern unsigned long GetLocalIp();
extern unsigned long GetDomainIp(char domainname[250]);
/*
long GetSocketEventId(SOCKET remotesock){
long EventId;
HANDLE hevent;
hevent=CreateEvent(NULL,0,0,0);
WSANETWORKEVENTS socket_events;
EventId=FD_NOEVENT;
if(WSAEventSelect(remotesock,hevent,FD_ACCEPT|FD_CONNECT|FD_
READ|FD_WRITE|FD_CLOSE)==SOCKET_ERROR) return EventId;
WSAEnumNetworkEvents(remotesock,hevent,&socket_events);
if(socket_events.lNetworkEvents!=0){
switch(socket_events.lNetworkEvents){
case FD_ACCEPT:EventId=FD_ACCEPT;break;
case FD_CONNECT:EventId=FD_CONNECT;break;
case FD_READ:EventId=FD_READ;break;
case FD_WRITE:EventId=FD_WRITE;break;
case FD_CLOSE:EventId=FD_CLOSE;break;
case FD_OOB:EventId=FD_OOB;break;
default:EventId=FD_NOEVENT;break;
}
}
else EventId=FD_NOEVENT;
return EventId;
}
//
unsigned long GetLocalIp()
{
char IP[MAX_PATH],*ip;
char pc_name[80];
struct in_addr in;
struct hostent *host;
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested=MAKEWORD(2,0);
ip=IP;
strcpy(ip,"Ip not get!");
if(WSAStartup(wVersionRequested,&wsaData)) return 0;
if(gethostname(pc_name,80)==SOCKET_ERROR){
WSACleanup();
return 0;
}
if(!(host=gethostbyname(pc_name))){
WSACleanup();
return 0;
}
in.s_addr=*((unsigned long *)host->h_addr_list[0]);
strcpy(ip,inet_ntoa(in));
WSACleanup();
return in.s_addr;
}
//
unsigned long GetDomainIp(char domainname[250])
{
char IP[MAX_PATH],*ip;
struct in_addr in;
struct hostent *host;
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested=MAKEWORD(2,0);
ip=IP;
strcpy(ip,"Ip not get!");
if(WSAStartup(wVersionRequested,&wsaData)) return 0;
if(!(host=gethostbyname(domainname))){
WSACleanup();
return 0;
}
in.s_addr=*((unsigned long *)host->h_addr_list[0]);
strcpy(ip,inet_ntoa(in));
WSACleanup();
return in.s_addr;
}
*/
//
//
UINT HttpReciveThread(LPVOID info){ //针对客户端的接收处理线程
LPSOCKINFO psockinfo; 
SOCKET sourcesock,destsock;
char data[MAXDATALEN];
long eventid;
int datalen;
psockinfo=(LPSOCKINFO)info;
sourcesock=psockinfo->sourcesock;
destsock=psockinfo->destsock;
TRACE("deail recive thread ok!\r\n");
while(true){
eventid=GetSocketEventId(sourcesock);
switch(eventid){
case FD_CLOSE:
TRACE("s fdclosed\r\n");
closesocket(destsock);
return 1;
break;
default:break;
}
eventid=GetSocketEventId(destsock);
switch(eventid){
case FD_CLOSE:
closesocket(sourcesock);
TRACE("d fdclosed\r\n");
return 1;
break;
default:break;
}
datalen=recv(sourcesock,data,sizeof(data),0);
if(datalen==0){
closesocket(sourcesock);
closesocket(destsock);
TRACE("s fdclosed\r\n");
break;
}
if(datalen>0){
while(!send(destsock,data,datalen,0));
}
Sleep(1);
}
return 1;
}
//
UINT HttpSendThread(LPVOID info){ //针对远程端的接收处理线程
LPSOCKINFO psockinfo;
SOCKET sourcesock,destsock;
char data[MAXDATALEN];
long eventid;
int datalen;
psockinfo=(LPSOCKINFO)info;
sourcesock=psockinfo->sourcesock;
destsock=psockinfo->destsock;
TRACE("deail send thread ok!\r\n");
while(true){
eventid=GetSocketEventId(sourcesock);
switch(eventid){
case FD_CLOSE:
TRACE("s fdclosed\r\n");
closesocket(destsock);
return 1;
break;
default:break;
}
eventid=GetSocketEventId(destsock);
switch(eventid){
case FD_CLOSE:
closesocket(sourcesock);
TRACE("d fdclosed\r\n");
return 1;
break;
default:break;
}
datalen=recv(destsock,data,sizeof(data),0);
if(datalen==0){
closesocket(sourcesock);
closesocket(destsock);
TRACE("d fdclosed\r\n");
break;
}
if(datalen>0){
while(!send(sourcesock,data,datalen,0));
}
Sleep(1);
}
return 1;
}
//
//
UINT HttpProxyServerThread(LPVOID info){ //针对一次服务的线程
LPCLIENTINFO pclientinfo;     //定义客户端结构体指针
SOCKET connectsock,clientsock;
sockaddr_in remotesock_addr;
char data[MAXDATALEN],url[250],temp[250],httpurl[250],portnum[10];
int datalen,i,index_start,index_end,port;
CString HttpString,UrlString,PortString;
pclientinfo=(LPCLIENTINFO)info; //pclientinfo指针指向客户端结构体地址
clientsock=pclientinfo->clientsock; //获得客户端的socket
ZeroMemory((void *)data,sizeof(data));
datalen=recv(clientsock,data,sizeof(data),0); //获得客户端的请求信息
if(datalen<=0){
closesocket(clientsock);
return 0;
}
HttpString.Format("%s",data);
UrlString=HttpString; //得到http协议请求字符串
TRACE("get http string:\r\n");
TRACE(HttpString);
index_start=HttpString.Find("Host: ",0); //寻找url标记
if(index_start<=0){
closesocket(clientsock);
return 0;
}
index_end=HttpString.Find("\r\n",index_start);
if(index_end<=0){
closesocket(clientsock);
return 0;
}
UrlString=HttpString.Mid(index_start+6,index_end-index_start-6); //读取 url字符串
TRACE("\r\n get url:");
TRACE(UrlString);
wsprintf(url,"%s",UrlString);
strcpy(temp,url);
strcat(temp,":");
datalen=strlen(temp);
if(HttpString.Find("GET",0)==0){ //判断get命令,并处理
index_start=HttpString.Find(temp,0);
strcpy(httpurl,"http://");
if(index_start>0){
index_end=HttpString.Find("/",index_start);
if(index_end<=0){
closesocket(clientsock);
return 0;
}
PortString=HttpString.Mid(index_start+datalen,index_end-index_start-datalen);
port=atoi(PortString);
strcat(httpurl,temp);
itoa(port,portnum,sizeof(portnum));
strcat(httpurl,portnum);
strcat(httpurl,"/");
}
else{
port=80;
strcat(httpurl,url);
strcat(httpurl,"/");
}
TRACE("get http url:%s\r\n",httpurl);
HttpString.Replace(httpurl,"/");
HttpString.Replace("Proxy-","");
HttpString.Replace("HTTP/1.0","HTTP/1.1");
}
else if(HttpString.Find("CONNECT",0)==0){ //判断connect命令并处理
index_start=HttpString.Find(temp,0);
if(index_start>0){
index_end=HttpString.Find(" ",index_start);
if(index_end<=0){
closesocket(clientsock);
return 0;
}
PortString=HttpString.Mid(index_start+datalen,index_end-index_start-datalen);
port=atoi(PortString);
}
else{
closesocket(clientsock);
return 0;
}
}
TRACE("get new http string:\r\n");
TRACE(HttpString);
remotesock_addr.sin_family=AF_INET;
remotesock_addr.sin_port=htons(port);
remotesock_addr.sin_addr.S_un.S_addr=GetDomainIp(url);
connectsock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(connect(connectsock,(const sockaddr *)&remotesock_addr,sizeof(remotesock_addr))==INVALID_SOCKET){ //连接远程主机
closesocket(clientsock);
return 0;
}
TRACE("\r\nconnect to remote ip ok\r\n"); 
ZeroMemory((void *)data,sizeof(data));
wsprintf(data,"%s",HttpString);
datalen=strlen(data);
if(HttpString.Find("CONNECT",0)<0) while(!send(connectsock,data,datalen,0));
else{
strcpy(data,"HTTP/1.0 200 Connection established\r\nProxy-agent: CHTTPPROXY V1.0 powered by shadow\r\n\r\n");
datalen=strlen(data);
while(!send(clientsock,data,datalen,0));
}
httpsockinfo.sourcesock=clientsock;
httpsockinfo.destsock=connectsock;
AfxBeginThread(HttpReciveThread,(LPVOID)&httpsockinfo); //抛出处理线程 
AfxBeginThread(HttpSendThread,(LPVOID)&httpsockinfo); //
Sleep(100);
return 1;
}
//
UINT StartHttpProxy(LPVOID info){ //端口监听线程
SOCKET NewSock;     //保存监听到的远程客户端socket
int socklen;
sockaddr_in serversock,remotesock_addr;
serversock.sin_family=AF_INET;
serversock.sin_addr.S_un.S_addr=INADDR_ANY;
serversock.sin_port=htons(HttpListenPort);
HttpListenSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //建立监听套接字
if(HttpListenSock==INVALID_SOCKET) return 0;
if(bind(HttpListenSock,(const sockaddr *)&serversock,   //绑定服务器端套接字
sizeof(serversock))==SOCKET_ERROR) return 0;
listen(HttpListenSock,BACKUP);                          //开始监听
socklen=sizeof(remotesock_addr);
TRACE("start http proxy thread while\r\n");
while(true){                                            //无限循环监听客户连接
NewSock=accept(HttpListenSock,(sockaddr *)&remotesock_addr,&socklen);
TRACE("waitting ok...\r\n");
if(NewSock==INVALID_SOCKET){
Sleep(1);
continue;
}
ZeroMemory((void *)&HttpClientInfo,sizeof(CLIENTINFO)); //清空HttpClientInfo结构
HttpClientInfo.clientsock=NewSock;   //监听到请求客户端的socket
HttpClientInfo.clientsock_addr=remotesock_addr; //保存请求客户端的信息
TRACE("start proxy thread\r\n");
AfxBeginThread(HttpProxyServerThread,(LPVOID)&HttpClientInfo); //启动代理服务线程
Sleep(100);
}
return 1;
}
//
CHTTPPROXY::CHTTPPROXY()
{
WSADATA WsaData;
WORD wsaVer;
wsaVer=MAKEWORD(2,0);
WsaStartupOk=false;
if(WSAStartup(wsaVer,&WsaData)!=SOCKET_ERROR) WsaStartupOk=true;
}

CHTTPPROXY::~CHTTPPROXY()
{
if(WsaStartupOk){
WSACleanup();
}
}

int CHTTPPROXY::StartProxy(int listenport)
{
HttpListenPort=listenport;
AfxBeginThread(StartHttpProxy,(LPVOID)NULL);
return 1;
}


/*=========================================================
FILE:HTTPPROXY.h
==========================================================*/
class CHTTPPROXY 
{
public:
int StartProxy(int listenport);
bool WsaStartupOk;
CHTTPPROXY();
virtual ~CHTTPPROXY();

};

/*==================================================
FILE:stdafx.h
===================================================*/
#include 
#include 
#include 
#include


注:不要忘了在link选项中添加wsock32.lib和ws2_32.lib,或在文件前部加上如下语句:
#paragma comment(lib,"wsock32.lib")
#paragma comment(lib,"ws2_32.lib")

本代码在win2k和vc6.0下编译成功~~
用法,把这几个文件添加到你的项目中,在WinMain()中添加如下代码:
CHTTPPROXY httpproxy;
httpproxy.StartProxy(7890);
有问题mailto me! 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -