仅用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 fileinput模块使用实例
Jun 03 Python
基于Python闭包及其作用域详解
Aug 28 Python
使用Python+Splinter自动刷新抢12306火车票
Jan 03 Python
Python设计模式之中介模式简单示例
Jan 09 Python
Django中的Signal代码详解
Feb 05 Python
人生苦短我用python python如何快速入门?
Mar 12 Python
Flask框架各种常见装饰器示例
Jul 17 Python
numpy中loadtxt 的用法详解
Aug 03 Python
Python检查和同步本地时间(北京时间)的实现方法
Dec 03 Python
linux安装python修改默认python版本方法
Mar 31 Python
pytest中文文档之编写断言
Sep 12 Python
Python关于反射的实例代码分享
Feb 20 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 IPV6正则表达式验证代码
2010/02/16 PHP
php XMLWriter类的简单示例代码(RSS输出)
2011/09/30 PHP
兼容PHP和Java的des加密解密代码分享
2014/06/26 PHP
非常经典的PHP文件上传类分享
2016/05/15 PHP
小试JQuery的AutoComplete插件
2011/05/04 Javascript
获得所有表单值的JQuery实现代码[IE暂不支持]
2012/05/24 Javascript
extjs tabpanel限制选项卡数量实现思路及代码
2013/04/02 Javascript
关于jquery.validate1.9.0前台验证的使用介绍
2013/04/26 Javascript
Javascript全局变量var与不var的区别深入解析
2013/12/09 Javascript
js鼠标点击图片切换效果代码分享
2015/08/26 Javascript
jquery trigger函数执行两次的解决方法
2016/02/29 Javascript
jQuery弹出下拉列表插件(实现kindeditor的@功能)
2016/08/16 Javascript
详解AngularJs中$resource和restfu服务端数据交互
2016/09/21 Javascript
原生js实现无限循环轮播图效果
2017/01/20 Javascript
ES6(ECMAScript 6)新特性之模板字符串用法分析
2017/04/01 Javascript
微信小程序如何获知用户运行小程序的场景教程
2017/05/17 Javascript
jQuery 利用ztree实现树形表格的实例代码
2017/09/27 jQuery
javascript实现计算指定范围内的质数示例
2018/12/29 Javascript
Vue+Django项目部署详解
2019/05/30 Javascript
JavaScript表格隔行变色和Tab标签页特效示例【附jQuery版】
2019/07/11 jQuery
IntelliJ IDEA编辑器配置vue高亮显示
2019/09/26 Javascript
vue 实现移动端键盘搜索事件监听
2019/11/06 Javascript
vue中实现点击变成全屏的多种方法
2020/09/27 Javascript
Python面向对象class类属性及子类用法分析
2018/02/02 Python
Python爬取视频(其实是一篇福利)过程解析
2019/08/01 Python
Python模拟FTP文件服务器的操作方法
2020/02/18 Python
matplotlib事件处理基础(事件绑定、事件属性)
2021/02/03 Python
Canvas与图片压缩的示例代码
2017/11/28 HTML / CSS
电脑教师的教学自我评价
2013/11/26 职场文书
酒店总经理工作职责
2013/12/13 职场文书
护理毕业生自我鉴定
2014/02/11 职场文书
毕业生简历自我评价范文
2014/04/09 职场文书
中层干部竞聘演讲稿
2014/05/15 职场文书
先进事迹材料怎么写
2014/12/30 职场文书
Java中的随机数Random
2022/03/17 Java/Android
Javascript中Microtask和Macrotask鲜为人知的知识点
2022/04/02 Javascript