仅用50行Python代码实现一个简单的代理服务器


Posted in Python onApril 08, 2015

之前遇到一个场景是这样的:

我在自己的电脑上需要用mongodb图形客户端,但是mongodb的服务器地址没有对外网开放,只能通过先登录主机A,然后再从A连接mongodb服务器B。

本来想通过ssh端口转发的,但是我没有从机器A连接ssh到B的权限。于是就自己用python写一个。

 

原理很简单。

1.开一个socket server监听连接请求

2.每接受一个客户端的连接请求,就往要转发的地址建一条连接请求。即client->proxy->forward。proxy既是socket服务端(监听client),也是socket客户端(往forward请求)。

3.把client->proxy和proxy->forward这2条socket用字典给绑定起来。

4.通过这个映射的字典把send/recv到的数据原封不动的传递

 

下面上代码。
 

#coding=utf-8 
import socket 
import select 
import sys 
  
to_addr = ('xxx.xxx.xx.xxx', 10000)#转发的地址 
  
class Proxy: 
  def __init__(self, addr): 
    self.proxy = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
    self.proxy.bind(addr) 
    self.proxy.listen(10) 
    self.inputs = [self.proxy] 
    self.route = {} 
  
  def serve_forever(self): 
    print 'proxy listen...' 
    while 1: 
      readable, _, _ = select.select(self.inputs, [], []) 
      for self.sock in readable: 
        if self.sock == self.proxy: 
          self.on_join() 
        else: 
          data = self.sock.recv(8096) 
          if not data: 
            self.on_quit() 
          else: 
            self.route[self.sock].send(data) 
  
  def on_join(self): 
    client, addr = self.proxy.accept() 
    print addr,'connect' 
    forward = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    forward.connect(to_addr) 
    self.inputs += [client, forward] 
    self.route[client] = forward 
    self.route[forward] = client 
  
  def on_quit(self): 
    for s in self.sock, self.route[self.sock]: 
      self.inputs.remove(s) 
      del self.route[s] 
      s.close() 
  
if __name__ == '__main__': 
  try: 
    Proxy(('',12345)).serve_forever()#代理服务器监听的地址 
  except KeyboardInterrupt: 
    sys.exit(1)
Python 相关文章推荐
matplotlib在python上绘制3D散点图实例详解
Dec 09 Python
Python实现带下标索引的遍历操作示例
May 30 Python
关于python中密码加盐的学习体会小结
Jul 15 Python
Python numpy数组转置与轴变换
Nov 15 Python
Python turtle库绘制菱形的3种方式小结
Nov 23 Python
Python 3.8 新功能来一波(大部分人都不知道)
Mar 11 Python
Pycharm及python安装详细教程(图解)
Jul 31 Python
Python求区间正整数内所有素数之和的方法实例
Oct 13 Python
python 如何引入协程和原理分析
Nov 30 Python
详解使用scrapy进行模拟登陆三种方式
Feb 21 Python
python中os.path.join()函数实例用法
May 26 Python
Python实现制作销售数据可视化看板详解
Nov 27 Python
用Python实现一个简单的能够发送带附件的邮件程序的教程
Apr 08 #Python
Python 创建子进程模块subprocess详解
Apr 08 #Python
Python中使用gzip模块压缩文件的简单教程
Apr 08 #Python
Python使用scrapy抓取网站sitemap信息的方法
Apr 08 #Python
Python中用format函数格式化字符串的用法
Apr 08 #Python
简单介绍Python中的JSON模块
Apr 08 #Python
Python实现把xml或xsl转换为html格式
Apr 08 #Python
You might like
PHP实践教程之过滤、验证、转义与密码详解
2017/07/24 PHP
Firefox div高度自适应
2009/04/28 Javascript
JavaScript中关于indexOf的使用方法与问题小结
2010/08/05 Javascript
JavaScript限定复选框的选择个数示例代码
2013/08/25 Javascript
JS获取当前网址、主机地址项目根路径
2013/11/19 Javascript
get(0).tagName获得作用标签示例代码
2014/10/08 Javascript
javascript实现的简单计时器
2015/07/19 Javascript
基于Bootstrap+jQuery.validate实现表单验证
2016/05/30 Javascript
详解使用angularjs的ng-options时如何设置默认值(初始值)
2017/07/18 Javascript
基于vue中解决v-for使用报红并出现警告的问题
2018/03/03 Javascript
浅析Vue中method与computed的区别
2018/03/06 Javascript
vue2.0 资源文件assets和static的区别详解
2018/04/08 Javascript
详解Angular如何正确的操作DOM
2018/07/06 Javascript
vue在手机中通过本机IP地址访问webApp的方法
2018/08/15 Javascript
Vue实现表格中对数据进行转换、处理的方法
2018/09/06 Javascript
Javascript迭代、递推、穷举、递归常用算法实例讲解
2019/02/01 Javascript
js纯前端实现腾讯cos文件上传功能的示例代码
2019/05/14 Javascript
150行代码带你实现微信小程序中的数据侦听
2019/05/17 Javascript
js实现双色球效果
2020/08/02 Javascript
在Vue 中获取下拉框的文本及选项值操作
2020/08/13 Javascript
antd-DatePicker组件获取时间值,及相关设置方式
2020/10/27 Javascript
[47:06]DOTA2上海特级锦标赛主赛事日 - 4 败者组第五轮 MVP.Phx VS EG第一局
2016/03/05 DOTA
使用Python脚本实现批量网站存活检测遇到问题及解决方法
2016/10/11 Python
Python cookbook(数据结构与算法)同时对数据做转换和换算处理操作示例
2018/03/23 Python
解决nohup重定向python输出到文件不成功的问题
2018/05/11 Python
Django使用Channels实现WebSocket的方法
2019/07/28 Python
Python基于numpy模块实现回归预测
2020/05/14 Python
容易被忽略的Python内置类型
2020/09/03 Python
input元素的url类型和email类型简介
2012/07/11 HTML / CSS
致跳远、跳高运动员广播稿
2014/01/09 职场文书
优秀求职信范文分享
2014/01/26 职场文书
超市开店计划书
2014/04/26 职场文书
商务经理岗位职责
2014/07/30 职场文书
个人简历求职信范文
2015/03/20 职场文书
庭外和解协议书
2016/03/23 职场文书
Python 批量下载阴阳师网站壁纸
2021/05/19 Python