仅用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 09 Python
Python遍历文件夹和读写文件的实现代码
Aug 28 Python
shell命令行,一键创建 python 模板文件脚本方法
Mar 20 Python
解决每次打开pycharm直接进入项目的问题
Oct 28 Python
python 判断三个数字中的最大值实例代码
Jul 24 Python
python中用logging实现日志滚动和过期日志删除功能
Aug 20 Python
python同步两个文件夹下的内容
Aug 29 Python
Cython编译python为so 代码加密示例
Dec 23 Python
Windows上安装tensorflow  详细教程(图文详解)
Feb 04 Python
python实现简单俄罗斯方块
Mar 13 Python
python 最简单的实现适配器设计模式的示例
Jun 30 Python
Django后端分离 使用element-ui文件上传方式
Jul 12 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
一个用php3编写的简单计数器
2006/10/09 PHP
php cli模式学习(PHP命令行模式)
2013/06/03 PHP
JavaScript更改class和id的方法
2008/10/10 Javascript
用jquery实现的一个超级简单的下拉菜单
2014/05/18 Javascript
JavaScript学习笔记之DOM基础 2.4
2015/08/14 Javascript
JavaScript数据推送Comet技术详解
2016/04/07 Javascript
javascript实现滚动效果的数字时钟实例
2016/07/21 Javascript
js表单元素checked、radio被选中的几种方法(详解)
2016/08/22 Javascript
js 弹出虚拟键盘修改密码的简单实例
2016/10/10 Javascript
Vue自定义指令介绍(2)
2016/12/08 Javascript
js实现淡入淡出轮播切换功能
2017/01/13 Javascript
js实现贪吃蛇小游戏(容易理解)
2017/01/22 Javascript
JavaScript输出所选择起始与结束日期的方法
2017/07/12 Javascript
VueJs 将接口用webpack代理到本地的方法
2017/11/27 Javascript
Vue CLI3搭建的项目中路径相关问题的解决
2018/09/17 Javascript
javascript实现日历效果
2019/06/17 Javascript
Vue-CLI项目中路由传参的方式详解
2019/09/01 Javascript
vuex+axios+element-ui实现页面请求loading操作示例
2020/02/02 Javascript
angular组件间传值测试的方法详解
2020/05/07 Javascript
[03:12]2016完美“圣”典风云人物:单车专访
2016/12/02 DOTA
[36:20]完美世界DOTA2联赛PWL S3 access vs Rebirth 第一场 12.17
2020/12/18 DOTA
[01:03:18]DOTA2-DPC中国联赛 正赛 RNG vs Dynasty BO3 第一场 1月29日
2021/03/11 DOTA
python 实现堆排序算法代码
2012/06/05 Python
Python获取远程文件大小的函数代码分享
2014/05/13 Python
Python中实现从目录中过滤出指定文件类型的文件
2015/02/02 Python
Python3实战之爬虫抓取网易云音乐的热门评论
2017/10/09 Python
使用python 爬虫抓站的一些技巧总结
2018/01/10 Python
Python高级特性切片(Slice)操作详解
2018/09/27 Python
TensorFlow车牌识别完整版代码(含车牌数据集)
2019/08/05 Python
深入了解python列表(LIST)
2020/06/08 Python
python 进制转换 int、bin、oct、hex的原理
2021/01/13 Python
应届毕业生自荐信例文
2014/02/26 职场文书
应届生找工作求职信
2014/06/24 职场文书
2014年房产经纪人工作总结
2014/12/08 职场文书
完美处理python与anaconda环境变量的冲突问题
2021/04/07 Python
MySQL读取JSON转换的方式
2022/03/18 MySQL