仅用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多线程编程简单介绍
Apr 13 Python
Python使用SQLite和Excel操作进行数据分析
Jan 20 Python
python2.7读取文件夹下所有文件名称及内容的方法
Feb 24 Python
python针对excel的操作技巧
Mar 13 Python
Python实现的寻找前5个默尼森数算法示例
Mar 25 Python
Pycharm设置界面全黑的方法
May 23 Python
对numpy中向量式三目运算符详解
Oct 31 Python
python实现在遍历列表时,直接对dict元素增加字段的方法
Jan 15 Python
我用Python抓取了7000 多本电子书案例详解
Mar 25 Python
Pytorch: 自定义网络层实例
Jan 07 Python
Python使用re模块验证危险字符
May 21 Python
Python 如何调试程序崩溃错误
Aug 03 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乱码问题
2012/03/25 PHP
php实现多张图片上传加水印技巧
2013/04/18 PHP
php array_values 返回数组的值实例详解
2016/11/17 PHP
PHP空值检测函数与方法汇总
2017/11/19 PHP
如何用javascript判断录入的日期是否合法
2007/01/08 Javascript
Expandable "Detail" Table Rows
2007/08/29 Javascript
javascript 匿名函数的理解(透彻版)
2010/01/28 Javascript
node.js中的fs.createWriteStream方法使用说明
2014/12/17 Javascript
JavaScript测试工具之Karma-Jasmine的安装和使用详解
2015/12/03 Javascript
把多个JavaScript函数绑定到onload事件处理函数上的方法
2016/09/04 Javascript
jQuery常用样式操作实例分析(获取、设置、追加、删除、判断等)
2016/09/08 Javascript
js实现html table 行,列锁定的简单实例
2016/10/13 Javascript
php 修改密码实现代码
2017/05/24 Javascript
深入浅析Vue.js 中的 v-for 列表渲染指令
2018/11/19 Javascript
使用canvas实现一个vue弹幕组件功能
2018/11/30 Javascript
react配置antd按需加载的使用
2019/02/11 Javascript
深入浅析nuxt.js基于ssh的vue通用框架
2019/05/21 Javascript
jquery实现动态改变css样式的方法分析
2019/05/27 jQuery
layer弹出层倒计时关闭的实现方法
2019/09/27 Javascript
Python中使用items()方法返回字典元素对的教程
2015/05/21 Python
python字典基本操作实例分析
2015/07/11 Python
使用Python生成随机密码的示例分享
2016/02/18 Python
Flask框架web开发之零基础入门
2018/12/10 Python
python批量修改图片尺寸,并保存指定路径的实现方法
2019/07/04 Python
关于Python-faker的函数效果一览
2019/11/28 Python
Python urlopen()和urlretrieve()用法解析
2020/01/07 Python
Currentbody西班牙:美容仪专家
2019/09/28 全球购物
俄罗斯香水和化妆品在线商店:Aroma-butik
2020/02/28 全球购物
秋季运动会加油稿200字
2014/01/11 职场文书
优秀班集体获奖感言
2014/02/03 职场文书
大学毕业感言100字
2014/02/03 职场文书
危爆物品安全大检查大整治工作方案
2014/05/03 职场文书
团日活动总结报告
2014/06/25 职场文书
大学生创业事迹材料
2014/12/30 职场文书
入党转正介绍人意见
2015/06/03 职场文书
win11高清晰音频管理器在哪里?win11找不到高清晰音频管理器解决办法
2022/04/08 数码科技