仅用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字符串逐字符或逐词反转方法
May 21 Python
Python中逗号的三种作用实例分析
Jun 08 Python
python通过ffmgep从视频中抽帧的方法
Dec 05 Python
总结python中pass的作用
Feb 27 Python
PyQt5 窗口切换与自定义对话框的实例
Jun 20 Python
Python3.8对可迭代解包的改进及用法详解
Oct 15 Python
python统计字符串中字母出现次数代码实例
Mar 02 Python
利用python实现凯撒密码加解密功能
Mar 31 Python
Django celery异步任务实现代码示例
Nov 26 Python
使用Django的JsonResponse返回数据的实现
Jan 15 Python
Ubuntu20下的Django安装的方法步骤
Jan 24 Python
OpenCV-Python实现图像平滑处理操作
Jun 08 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获取类中常量,属性,及方法列表的方法
2009/04/09 PHP
php递归实现无限分类生成下拉列表的函数
2010/08/08 PHP
php处理文件的小例子(解压缩,删除目录)
2013/02/03 PHP
PHP测试成功的邮件发送案例
2015/10/26 PHP
PHP实现的自定义数组排序函数与排序类示例
2016/11/18 PHP
js模拟实现Array的sort方法
2007/12/11 Javascript
jQuery 菜单随滚条改为以定位方式(固定要浏览器顶部)
2012/05/24 Javascript
JQuery调webservice实现邮箱验证(检测是否可用)
2013/05/21 Javascript
JavaScript Promise启示录
2014/08/12 Javascript
基于jQuery实现仿淘宝套餐选择插件
2015/03/04 Javascript
javascript实现通过表格绘制颜色填充矩形的方法
2015/04/21 Javascript
JavaScript中pop()方法的使用教程
2015/06/09 Javascript
简单理解js的冒泡排序
2016/12/19 Javascript
JavaScript数组复制详解
2017/02/02 Javascript
js实现横向拖拽导航条功能
2017/02/17 Javascript
详解Angular4中路由Router类的跳转navigate
2017/06/09 Javascript
JavaScript转换数据库DateTime字段类型方法
2017/06/27 Javascript
简单学习5种处理Vue.js异常的方法
2019/06/17 Javascript
JavaScript实现更换背景图片
2019/10/18 Javascript
[02:25]DOTA2英雄基础教程 虚空假面
2014/01/02 DOTA
[03:18]DOTA2亚洲邀请赛小组赛第一日 RECAP赛事回顾
2015/01/30 DOTA
[02:12]Dota 2 推出全新英雄—— 电炎绝手
2019/08/23 DOTA
Python中使用items()方法返回字典元素对的教程
2015/05/21 Python
Python实现连接两个无规则列表后删除重复元素并升序排序的方法
2018/02/05 Python
python抽取指定url页面的title方法
2018/05/11 Python
Python3enumrate和range对比及示例详解
2019/07/13 Python
Python全局锁中如何合理运用多线程(多进程)
2019/11/06 Python
在对linux系统分区进行格式化时需要对磁盘簇(或i节点密度)的大小进行选择,请说明选择的原则
2012/01/13 面试题
小学运动会入场式解说词
2014/02/18 职场文书
《画家乡》教学反思
2014/04/22 职场文书
个人纪律作风整改措施思想汇报
2014/10/12 职场文书
2014年企业党建工作总结
2014/12/18 职场文书
赞美教师的句子
2019/09/02 职场文书
基于python实现银行管理系统
2021/04/20 Python
恶魔之树最顶端的三颗果实 震震果实上榜,第一可以制造岩浆
2022/03/18 日漫
Python实现仓库管理系统
2022/05/30 Python