自己写非阻塞代理服务器 proxy 之C语言版

来源(博客频道 - CSDN.NET)

From: http://blog.csdn.net/littlethunder/article/details/8959967

自己写非阻塞代理服务器 proxy 之C语言版

标签: 代理服务器proxy socket linux ctornado

2013-05-22 13:59 10324人阅读

分类: Tornado(12) C(4)

版权声明:本文为博主原创文章,未经博主允许不得转载。

代理服务器的工作流程就是:把client的访问请求发送到proxy,proxy再把这些数据转到server,然后server对这个请求产生响应数据,发送到proxy,proxy再把这些数据转到client。经过了proxy,那就可以做好多事情了哈,可以自己设置个墙,自己设置访问优先级,统计流量啥的就不说了,反正可以做各种好玩的。因为刚开始做,做个简单的,以后可以慢慢加功能。

proxy的Linux C 语言版如下所示:

#include<stdio.h>
#include<poll.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>

#define ADDR "127.0.0.1"
#define PORT 8080
#define PORT_APACHE 8088
#define SIZE 1024

int main()
{
	int ret=0;
	int maxsocket;
	int apa,ser,cli;
	char buf[SIZE]={0};
	char apabuf[SIZE]={0};
	struct pollfd fds[5]={0};
	struct sockaddr_in apaaddr,seraddr,cliaddr;
	socklen_t clilen=sizeof(cliaddr);

	apaaddr.sin_family=AF_INET;
	apaaddr.sin_addr.s_addr=inet_addr(ADDR);
	apaaddr.sin_port=htons(PORT_APACHE);

	seraddr.sin_family=AF_INET;
	seraddr.sin_addr.s_addr=inet_addr(ADDR);
	seraddr.sin_port=htons(PORT);

	apa=socket(AF_INET,SOCK_STREAM,0);
	ser=socket(AF_INET,SOCK_STREAM,0);
	bind(ser,(struct sockaddr*)&seraddr,sizeof(seraddr));
	fds[0].fd=ser;
	fds[0].events=POLLIN;
	listen(fds[0].fd,5);
	while(1)
	{
		memset(buf,0,SIZE);
		memset(apabuf,0,SIZE);
		ret=poll(fds,sizeof(fds)/sizeof(fds[0]),-1);
		if(ret<0)
		{
			printf("poll error\n");
			break;
		}
		if(fds[0].revents&POLLIN)
		{
			cli=accept(fds[0].fd,(struct sockaddr*)&cliaddr,&clilen);
			recv(cli,buf,SIZE,0);
			printf("get from %s:%d-- %s\n",inet_ntoa(cliaddr.sin_addr),
			ntohs(cliaddr.sin_port),buf);
			connect(apa,(struct sockaddr*)&apaaddr,sizeof(apaaddr));
			send(apa,buf,SIZE,0);
			recv(apa,apabuf,SIZE,0);
			send(cli,apabuf,SIZE,0);
		}
	}
	return 0;
}


proxy的端口是8080,真正server的端口是8088。因为考虑到client发送connect请求可能不传数据或者恶意ddos攻击,所以用poll轮询client的连接请求,我在Proxy到server的连接中直接采用阻塞的方式,因为我知道这是安全的。接下来是真正的服务器,因为我把apache卸载了,所以先用python模拟一个代替一下先哈:

import tornado.web
import tornado.ioloop
from tornado.options import options,define,parse_command_line

define('port',default=8088,help='run this port',type=int)

class MainHandler(tornado.web.RequestHandler):
	def get(self):
		self.render('./a.html')

parse_command_line()
app=tornado.web.Application(
	[
		('/',MainHandler),
	],
)
app.listen(options.port)
tornado.ioloop.IOLoop.instance().start()


这还是我的老本行tornado,非常方便,a.html里面就是一句话,测试用的,如下:

<html>
	<head>
		<title>haha</title>
	</head>
	<body>
		This is a message from proxy.
	</body>
</html>


好了,现在看看效果:

Python模拟的真服务器运行效果图:



代理服务器运行效果图:



浏览器访问代理服务器效果图:



哈哈,这就做到最基本的代理功能。如果以后还有时间可以再加点东西搞一搞。

转载请注明:转自 http://blog.csdn.net/littlethunder/article/details/8959967

Link: http://www.asm32.net/article_details.aspx?id=7248


浏览次数 0 发布时间 2017/6/30 0:18:39 从属分类 Python 【评论】【 】【打印】【关闭
 
| www.asm32.net | 2006版 | 资料中心 | linux | asm/asm32 | C/C++ | VC++ | java | Python | 书签 | ASP.Net书签 | 京ICP备09029108号-1