仅用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基于itchat实现微信群消息同步机器人
Feb 27 Python
Ubuntu安装Jupyter Notebook教程
Oct 18 Python
对Tensorflow中的矩阵运算函数详解
Jul 27 Python
PyCharm代码提示忽略大小写设置方法
Oct 28 Python
使用python判断你是青少年还是老年人
Nov 29 Python
解析Python的缩进规则的使用
Jan 16 Python
Python基础之文件读取的讲解
Feb 16 Python
python 画3维轨迹图并进行比较的实例
Dec 06 Python
python numpy实现多次循环读取文件 等间隔过滤数据示例
Mar 14 Python
Jupyter notebook 启动闪退问题的解决
Apr 13 Python
django restframework serializer 增加自定义字段操作
Jul 15 Python
python实现监听键盘
Apr 26 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中使用socket方式GET、POST数据实例
2015/04/02 PHP
PHPMailer ThinkPHP实现自动发送邮件功能
2018/06/10 PHP
JS 动态获取节点代码innerHTML分析 [IE,FF]
2009/11/30 Javascript
js模拟类继承小例子
2010/07/17 Javascript
jQuery学习笔记(4)--Jquery中获取table中某列值的具体思路
2013/04/10 Javascript
JS操作图片(增,删,改) 例子
2013/04/17 Javascript
Node.js开源应用框架HapiJS介绍
2015/01/14 Javascript
基于Javascript实现倒计时功能
2016/02/22 Javascript
微信小程序 Nginx环境配置详细介绍
2017/02/14 Javascript
vue-router:嵌套路由的使用方法
2017/02/21 Javascript
JS如何设置元素样式的方法示例
2017/08/28 Javascript
JavaScript引用类型Date常见用法实例分析
2018/08/08 Javascript
一篇文章,教你学会Vue CLI 插件开发
2019/04/17 Javascript
Fetch超时设置与终止请求详解
2019/05/18 Javascript
Vue使用Ref跨层级获取组件的步骤
2021/01/25 Vue.js
Python3通过Luhn算法快速验证信用卡卡号的方法
2015/05/14 Python
Python设计模式之门面模式简单示例
2018/01/09 Python
Python读取YUV文件,并显示的方法
2018/12/04 Python
pyqt5实现绘制ui,列表窗口,滚动窗口显示图片的方法
2019/06/20 Python
Python字符编码转码之GBK,UTF8互转
2020/02/09 Python
完美解决ARIMA模型中plot_acf画不出图的问题
2020/06/04 Python
pandas处理csv文件的方法步骤
2020/10/16 Python
Python爬虫分析微博热搜关键词的实现代码
2021/02/22 Python
英国婴儿和儿童服装网站:Vertbaudet
2018/04/02 全球购物
Java面试题:请说出如下代码的输出结果
2013/04/22 面试题
厨师长岗位职责
2014/03/02 职场文书
《锄禾》教学反思
2014/04/08 职场文书
体育系毕业生求职自荐信
2014/04/16 职场文书
考试保密承诺书
2014/08/30 职场文书
教师党员自我剖析材料
2014/09/29 职场文书
检讨书范文1000字
2015/01/28 职场文书
mongodb清除连接和日志的正确方法分享
2021/09/15 MongoDB
CSS布局之浮动(float)和定位(position)属性的区别
2021/09/25 HTML / CSS
利用Python多线程实现图片下载器
2022/03/25 Python
JS精髓原型链继承及构造函数继承问题纠正
2022/06/16 Javascript
Java获取字符串编码格式实现思路
2022/09/23 Java/Android