HTTP代理源代码

原创 2007年10月10日 17:03:00
#pragma hdrstop

//---------------------------------------------------------------------------

#include <windows.h>
#include <stdio.h>

#define MAX_TOMEOUT 10000
#define MAX_SOCKET 5000
#define MAX_CHARBUFF 20480
#define MAX_HOSTNAME 256
#define DEFPORT 80
#define LISPORT 8471
#define DEFLISNUM 500
#define HEADLEN 7

DWORD WINAPI ProClientThread(LPVOID lpParam);
SOCKET SendHeadData(SOCKET ClientSocket,char *Msg,char *HMsg,int Datalen);
SOCKET GetServerAddr(char *Msg,int datalen);
//void ChangeSysInfo(char *Msg);
char * Get3Chars(char * Str,int *len);
void RecvSendData(SOCKET Rsck,SOCKET Ssck,char *SendBuf);
DWORD WINAPI RSThread(LPVOID lpParam);

char ErrorSendMsg[]="Http/1.1 403 Forbidden/r/n/r/n<body><h1>403 Forbidden</h1></body>";

struct sendofsck
{
SOCKET Rsck;
SOCKET Ssck;
char *Buff;
};

int main(int argc, char* argv[])
{
WSADATA WSAData;
if(WSAStartup(MAKEWORD(2,2), &WSAData))
return 1;

SOCKET ProServer= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(ProServer == SOCKET_ERROR)
return 1;

struct sockaddr_in ServerStk={0}, ClientCont={0};

ServerStk.sin_family = AF_INET;//inter模式
ServerStk.sin_port = htons(LISPORT);//监听端口
ServerStk.sin_addr.S_un.S_addr = INADDR_ANY;

if(bind(ProServer, (LPSOCKADDR) & ServerStk, sizeof(ServerStk)) == SOCKET_ERROR)
return 1;

if(listen(ProServer, DEFLISNUM) == SOCKET_ERROR)
return 1;

int ServerStkSize = sizeof(ClientCont);
SOCKET ServerBegin[MAX_SOCKET];
DWORD funid;
int i=0;
while(1)
{
ServerBegin[i] = accept(ProServer, (struct sockaddr *)&ClientCont, &ServerStkSize);
if(ServerBegin[i] == INVALID_SOCKET)
return 1;

//建立用户线程
if(CreateThread(NULL, 0, ProClientThread, (LPVOID)&ServerBegin[i], 0, &funid) == 0)
continue;

if(i++ > MAX_SOCKET) i = 0;
}
}
//---------------------------------------------------------------------------
DWORD WINAPI ProClientThread(LPVOID lpParam)
{
SOCKET ClientConSock = (SOCKET)*(SOCKET*)lpParam;

//以上是接受变量
char *ReceiveBuf = (char*)malloc(sizeof(char)*MAX_CHARBUFF);
char *SenderBuf = (char *)malloc(sizeof(char)*MAX_CHARBUFF);
char HeadBuf[MAX_HOSTNAME] = "";
memset(ReceiveBuf,0,MAX_CHARBUFF);
memset(SenderBuf,0,MAX_CHARBUFF);

int DataLen = 0,SendLen = 0,fags = 0,HedLen = 0;

//获取第一次的数据信息
DataLen = recv(ClientConSock,ReceiveBuf,MAX_CHARBUFF,0);

if(DataLen != SOCKET_ERROR && DataLen != 0)
{


//判断是何种服务器动作
if(!strncmpi(ReceiveBuf,"GET ",4))
{
strncpy(SenderBuf,ReceiveBuf,4);
SendLen = 4;
fags = 1;
}
else if(!strncmpi(ReceiveBuf,"HEAD ",5))
{
strncpy(SenderBuf,ReceiveBuf,5);
SendLen = 5;
fags = 2;
}
else if(!strncmpi(ReceiveBuf,"POST ",5))
{
strncpy(SenderBuf,ReceiveBuf,5);
SendLen = 5;
fags = 3;
}
else
{
send(ClientConSock,ErrorSendMsg,strlen(ErrorSendMsg),0);
goto ext;
}
//判断是不是以http打头的数据
if(strncmpi(ReceiveBuf+SendLen,"http://",HEADLEN))
{
send(ClientConSock,ErrorSendMsg,strlen(ErrorSendMsg),0);
goto ext;
}
//获得http://和/之间的数据,也就是域名
char * Getfp = Get3Chars(ReceiveBuf+SendLen+HEADLEN,&HedLen);

if(Getfp == NULL)
{
send(ClientConSock,ErrorSendMsg,strlen(ErrorSendMsg),0);
goto ext;
}

//获得域名信息,比如www.163.com
memcpy(HeadBuf,ReceiveBuf+SendLen+HEADLEN,HedLen);
//简单构造一个去掉了域名的请求报文
memcpy(SenderBuf+SendLen,Getfp,DataLen-HedLen-HEADLEN);

//sendheaddata函数用来确定主机位置,创建socket句柄和发送第一批数据
SOCKET ServerSocket = SendHeadData(ClientConSock,SenderBuf,HeadBuf,DataLen-HedLen+SendLen);

//POST方式则新建一线程用来发送,同时调用recvsenddata函数用来接受

if(ServerSocket != SOCKET_ERROR)
{
//何种动作
if(fags == 1||fags == 2)
//接受服务器发来的数据
RecvSendData(ServerSocket,ClientConSock,SenderBuf);
else if(fags == 3)
{
//准备线程的参数,用结构传递
struct sendofsck SendSck={0};
SendSck.Rsck = ClientConSock;
SendSck.Ssck = ServerSocket;
SendSck.Buff = ReceiveBuf;
DWORD funid;
//建立线程来接受post剩下的数据,然后调用函数接受服务器发来的数据
if(CreateThread(NULL, 0, RSThread, (LPVOID)&SendSck, 0, &funid) != 0)
RecvSendData(ServerSocket,ClientConSock,SenderBuf);
}
closesocket(ServerSocket);
}
}
else
send(ClientConSock,ErrorSendMsg,strlen(ErrorSendMsg),0);

//退出信息
ext:closesocket(ClientConSock);
free(ReceiveBuf);
free(SenderBuf);
return 0;
}
//---------------------------------------------------------------------------
SOCKET SendHeadData(SOCKET ClientSocket,char *Msg,char *HMsg,int DataLen)
{
//char *SendBuf = Msg;
//int sendlen = DataLen;

//获得头部信息(此函数包括连接服务器功能)
SOCKET ServerSocket = GetServerAddr(HMsg,DataLen);
if(ServerSocket == SOCKET_ERROR)
return SOCKET_ERROR;

//修改头部
//ChangeSysInfo(SendBuf);

//发送第一次的数据给服务器
if(send(ServerSocket,Msg,DataLen,0) == SOCKET_ERROR)
{
closesocket(ServerSocket);
return SOCKET_ERROR;
}
return ServerSocket;
}
//---------------------------------------------------------------------------
SOCKET GetServerAddr(char *Msg,int datalen)
{
char HostIp[MAX_HOSTNAME]="";
int HostPort=0;

char *fp = Msg;
//如果有端口,则停下
for(int i = 0;i < MAX_HOSTNAME && *fp != ':' && *fp != '/0';i++)
HostIp[i]=*fp++;
//取出端口信息
if(*fp == ':')
HostPort=atoi(fp+1);
else HostPort=DEFPORT;

//申请并填充结构
struct sockaddr_in ServerAddr;

ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(HostPort);

//填充IP,如果是域名,则转换为IP
if(HostIp[0] >= '0' && HostIp[0] <= '9')
ServerAddr.sin_addr.s_addr = inet_addr(HostIp);
else
{
//域名转为IP
struct hostent *pHost = gethostbyname(HostIp);
if(!pHost)
return SOCKET_ERROR;
memcpy(&ServerAddr.sin_addr,pHost->h_addr_list[0],sizeof(ServerAddr.sin_addr));
}

//设置连接
SOCKET ServerSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(ServerSocket == SOCKET_ERROR)
return SOCKET_ERROR;

//设置超时
int time_out=MAX_TOMEOUT;
if(setsockopt(ServerSocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&time_out,sizeof(time_out)) == SOCKET_ERROR)
return SOCKET_ERROR;

//连接
if(connect(ServerSocket,(SOCKADDR *)&ServerAddr,sizeof(ServerAddr)) == SOCKET_ERROR)
{
closesocket(ServerSocket);
return SOCKET_ERROR;
}

//返回连接句柄
return ServerSocket;
}
/*/---------------------------------------------------------------------------
void ChangeSysInfo(char *Msg)
{
//修改的具体选项
char HostBan[] = "User-Agent: Mozilla/4.0 (compatible; MSIE ";
char *fp = strstr(Msg,HostBan);
if(fp != NULL) strncpy(fp + strlen(HostBan),"8.8; Windows ZV",15);
}
//--------------------------------------------------------------------------- */
char * Get3Chars(char * Str,int *len)
{
//获得/之后的位置,也就是除去http和域名的那些
for(int i = 0;i < MAX_HOSTNAME-HEADLEN; i++)
{
if(Str[i] == '/')
{
*len = i;
return &Str[i];
}
}
return NULL;
}
//---------------------------------------------------------------------------
void RecvSendData(SOCKET Rsck,SOCKET Ssck,char *SendBuf)
{
//从a处接受信息发往b处
int sendlen = 100;
while(sendlen > 0)
{
if((sendlen = recv(Rsck,SendBuf,MAX_CHARBUFF,0)) <= 0)
break;
if(send(Ssck,SendBuf,sendlen,0) < 0)
break;
}
}
//---------------------------------------------------------------------------
DWORD WINAPI RSThread(LPVOID lpParam)
{
//接受到信息后,用相反的方向来从客户端接受剩下的post数据发往服务器
struct sendofsck SendSck={0};
memcpy((void*)&SendSck,lpParam,sizeof(SendSck));
RecvSendData(SendSck.Rsck,SendSck.Ssck,SendSck.Buff);
return 1;
}
//---------------------------------------------------------------------------
 

Javaweb开发基础视频教程之http协议

-
  • 1970年01月01日 08:00

一个http代理的代码

#include #include #include #include #include #include #include #define  MAXBUFLEN  20480#define  HTT...
  • iiprogram
  • iiprogram
  • 2008-05-16 09:20:00
  • 953

HTTP 代理服务器源码

  • 2008年11月05日 00:59
  • 255KB
  • 下载

http使用代理

if (null == strUrl) { System.out.println("URL信息不存在!"); retu...
  • jiangxuchen
  • jiangxuchen
  • 2012-03-13 10:38:33
  • 1182

HTTP源码

  • 2008年04月13日 13:37
  • 3KB
  • 下载

编写了一个简单的http代理服务器

单位一直使用ccproxy,破解版的。 不爽,于是,自己编写了一个简单的http代理服务器。 当然,功能还是和标题一样,简单的。 希望有高手一起开发。 争取日后国内一说起写代理服务器,就首先想...
  • lifan_3a
  • lifan_3a
  • 2014-07-06 02:21:20
  • 1528

Socks5代理服务器源码下载

  • 2009年04月23日 18:49
  • 732KB
  • 下载

简易HTTP代理的实现

编写一个简易的HTTP代理服务器,步骤其实很简单:      1.设置一个监听套接字gListen_Socket;      2.每当接受到客户端的请求之后,我们构建一个新的线程来继续监听客户端的请求...
  • lishuhuakai
  • lishuhuakai
  • 2014-05-23 12:30:30
  • 11456

HTTP 代理原理及实现(一)

Web 代理是一种存在于网络中间的实体,提供各式各样的功能。现代网络系统中,Web 代理无处不在。我之前有关 HTTP 的博文中,多次提到了代理对 HTTP 请求及响应的影响。今天这篇文章,我打算谈谈...
  • zbuger
  • zbuger
  • 2016-06-20 13:29:34
  • 2683

JAVA写HTTP代理服务器(二)-netty实现

接上一篇,因为是用BIO的一个连接一个线程去处理,对于HTTP这种短连接协议来说CPU开销是非常大的,就算加入了线程池也不能完美解决BIO的缺陷,所以可以用NIO进行服务器的优化,NIO基于IO多路复...
  • liwei2633
  • liwei2633
  • 2017-09-04 16:13:49
  • 3916
收藏助手
不良信息举报
您举报文章:HTTP代理源代码
举报原因:
原因补充:

(最多只允许输入30个字)