仅用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 相关文章推荐
Python中MySQL数据迁移到MongoDB脚本的方法
Apr 28 Python
python正则实现计算器功能
Dec 14 Python
利用python将json数据转换为csv格式的方法
Mar 22 Python
20行python代码实现人脸识别
May 05 Python
Django中自定义查询对象的具体使用
Oct 13 Python
keras 特征图可视化实例(中间层)
Jan 24 Python
Python识别html主要文本框过程解析
Feb 18 Python
使用Python发现隐藏的wifi
Mar 04 Python
tensorflow中tf.reduce_mean函数的使用
Apr 19 Python
Keras—embedding嵌入层的用法详解
Jun 10 Python
详解Python调用系统命令的六种方法
Jan 28 Python
pytorch交叉熵损失函数的weight参数的使用
May 24 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
MySQL修改密码方法总结
2008/03/25 PHP
PHP预定义变量9大超全局数组用法详解
2016/04/23 PHP
PHP判断是否是微信打开还是浏览器打开的方法
2019/02/27 PHP
Jquery+ajax请求data显示在GridView上(asp.net)
2010/08/27 Javascript
精心挑选的15款优秀jQuery 本特效插件和教程
2012/08/06 Javascript
jQuery中change事件用法实例
2014/12/26 Javascript
JavaScript中的Math.sin()方法使用详解
2015/06/15 Javascript
AngualrJS中每次$http请求时的一个遮罩层Directive
2016/01/26 Javascript
jQuery根据表单name获取值的方法
2016/05/24 Javascript
bootstrap模态框实现拖拽效果
2016/12/14 Javascript
Layui组件Table绑定行点击事件和获取行数据的方法
2018/08/19 Javascript
VUE组件中的 Drawer 抽屉实现代码
2019/08/06 Javascript
加速vue组件渲染之性能优化
2020/04/09 Javascript
js函数柯里化的方法和作用实例分析
2020/04/11 Javascript
vue+vant实现购物车全选和反选功能
2020/11/17 Vue.js
python书籍信息爬虫实例
2018/03/19 Python
python 获取毫秒数,计算调用时长的方法
2019/02/20 Python
Pandas之Dropna滤除缺失数据的实现方法
2019/06/25 Python
python面向对象 反射原理解析
2019/08/12 Python
python读取Excel表格文件的方法
2019/09/02 Python
浅析PEP570新语法: 只接受位置参数
2019/10/15 Python
python绘制玫瑰的实现代码
2020/03/02 Python
在pycharm中文件取消用 pytest模式打开的操作
2020/09/01 Python
python用tkinter实现一个简易能进行随机点名的界面
2020/09/27 Python
pip/anaconda修改镜像源,加快python模块安装速度的操作
2021/03/04 Python
阿联酋电子产品购物网站:Menakart
2017/09/15 全球购物
精灵市场:Pixie Market
2019/06/18 全球购物
Silk Therapeutics官网:清洁、抗衰老护肤品
2020/08/12 全球购物
Servlet的生命周期
2013/08/25 面试题
微博营销计划书
2014/01/10 职场文书
九一八事变演讲稿范文
2014/09/14 职场文书
社区六一儿童节活动总结
2015/02/11 职场文书
后勤工作个人总结
2015/02/28 职场文书
民主生活会主持词
2015/07/01 职场文书
2019学子的答谢词范本!
2019/07/05 职场文书
mysql的单列多值存储实例详解
2022/04/05 MySQL