Python实现网络端口转发和重定向的方法


Posted in Python onSeptember 19, 2016

本文实例讲述了Python实现网络端口转发和重定向的方法。分享给大家供大家参考,具体如下:

【任务】

需要将某个网络端口转发到另一个主机(forwarding),但可能会是不同的端口(redirecting)。

【解决方案】

两个使用threading和socket模块的类就能完成我们需要的端口转发和重定向。

#encoding=utf8
#author: walker摘自《Python Cookbook(2rd)》
#date: 2015-06-11
#function: 网络端口的转发和重定向(适用于python2/python3)
import sys, socket, time, threading
LOGGING = True
loglock = threading.Lock()
#打印日志到标准输出
def log(s, *a):
  if LOGGING:
    loglock.acquire()
    try:
      print('%s:%s' % (time.ctime(), (s % a)))
      sys.stdout.flush()
    finally:
      loglock.release()
class PipeThread(threading.Thread):
  pipes = []   #静态成员变量,存储通讯的线程编号
  pipeslock = threading.Lock()
  def __init__(self, source, sink):
    #Thread.__init__(self) #python2.2之前版本适用
    super(PipeThread, self).__init__()
    self.source = source
    self.sink = sink
    log('Creating new pipe thread %s (%s -> %s)',
        self, source.getpeername(), sink.getpeername())
    self.pipeslock.acquire()
    try:
      self.pipes.append(self)
    finally:
      self.pipeslock.release()
    self.pipeslock.acquire()
    try:
      pipes_now = len(self.pipes)
    finally:
      self.pipeslock.release()
    log('%s pipes now active', pipes_now)
  def run(self):
    while True:
      try:
        data = self.source.recv(1024)
        if not data:
          break
        self.sink.send(data)
      except:
        break
    log('%s terminating', self)
    self.pipeslock.acquire()
    try:
      self.pipes.remove(self)
    finally:
      self.pipeslock.release()
    self.pipeslock.acquire()
    try:
      pipes_left = len(self.pipes)
    finally:
      self.pipeslock.release()
    log('%s pipes still active', pipes_left)
class Pinhole(threading.Thread):
  def __init__(self, port, newhost, newport):
    #Thread.__init__(self) #python2.2之前版本适用
    super(Pinhole, self).__init__()
    log('Redirecting: localhost: %s->%s:%s', port, newhost, newport)
    self.newhost = newhost
    self.newport = newport
    self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.sock.bind(('', port))
    self.sock.listen(5) #参数为timeout,单位为秒
  def run(self):
    while True:
      newsock, address = self.sock.accept()
      log('Creating new session for %s:%s', *address)
      fwd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      fwd.connect((self.newhost, self.newport))
      PipeThread(newsock, fwd).start() #正向传送
      PipeThread(fwd, newsock).start() #逆向传送
if __name__ == '__main__':
  print('Starting Pinhole port fowarder/redirector')
  try:
    port = int(sys.argv[1])
    newhost = sys.argv[2]
    try:
      newport = int(sys.argv[3])
    except IndexError:
      newport = port
  except (ValueError, IndexError):
    print('Usage: %s port newhost [newport]' % sys.argv[0])
    sys.exit(1)
  #sys.stdout = open('pinhole.log', 'w') #将日志写入文件
  Pinhole(port, newhost, newport).start()

【讨论】

当你在管理一个网络时,即使是一个很小的网络,端口转发和重定向的功能有时也能给你很大的帮助。一些不在你的控制之下的应用或者服务可能是以硬连接的方式接入到某个特定的服务器的地址或端口。通过插入转发和重定向,你就能将对应用的连接请求发送到其他更合适的主机或端口上。

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python性能优化技巧
Mar 09 Python
Python面向对象编程中的类和对象学习教程
Mar 30 Python
python实现计算倒数的方法
Jul 11 Python
Python聚类算法之DBSACN实例分析
Nov 20 Python
Python中的函数式编程:不可变的数据结构
Oct 08 Python
python使用xlsxwriter实现有向无环图到Excel的转换
Dec 12 Python
Jupyter notebook在mac:linux上的配置和远程访问的方法
Jan 14 Python
pytorch实现mnist数据集的图像可视化及保存
Jan 14 Python
Keras框架中的epoch、bacth、batch size、iteration使用介绍
Jun 10 Python
python 5个实用的技巧
Sep 27 Python
Python: glob匹配文件的操作
Dec 11 Python
numpy实现RNN原理实现
Mar 02 Python
Python中__init__.py文件的作用详解
Sep 18 #Python
Python简单遍历字典及删除元素的方法
Sep 18 #Python
Python实现压缩与解压gzip大文件的方法
Sep 18 #Python
Python打包文件夹的方法小结(zip,tar,tar.gz等)
Sep 18 #Python
Python简单格式化时间的方法【strftime函数】
Sep 18 #Python
Python简单获取自身外网IP的方法
Sep 18 #Python
Python简单检测文本类型的2种方法【基于文件头及cchardet库】
Sep 18 #Python
You might like
phpmyadmin显示utf8_general_ci中文乱码的问题终级篇
2013/04/08 PHP
php遍历文件夹所有文件子文件夹函数代码
2013/11/27 PHP
jQuery Mobile + PHP实现文件上传
2014/12/12 PHP
ThinkPHP文件缓存类代码分享
2015/04/22 PHP
php组合排序简单实现方法
2016/10/15 PHP
php生成二维码图片方法汇总
2016/12/17 PHP
PHP实现抽奖功能实例代码
2020/06/30 PHP
一个JQuery操作Table的代码分享
2012/03/30 Javascript
基于js disabled="false"不起作用的解决办法
2013/06/26 Javascript
JS下拉框内容左右移动效果的具体实现
2013/07/10 Javascript
js的toLowerCase方法用法实例
2015/01/27 Javascript
如何解决ligerUI布局时Center中的Tab高度大小
2015/11/24 Javascript
javascript实现checkbox复选框实例代码
2016/01/10 Javascript
js点击文本框弹出可选择的checkbox复选框
2016/02/03 Javascript
Bootstrap组件学习之导航、标签、面包屑导航(精品)
2016/05/17 Javascript
jQuery实现表格行和列的动态添加与删除方法【测试可用】
2016/08/01 Javascript
JavaScript SHA512加密算法详细代码
2016/10/06 Javascript
AngularJS入门教程之多视图切换用法示例
2016/11/02 Javascript
MvcPager分页控件 适用于Bootstrap
2017/06/03 Javascript
JS实现滑动拼图验证功能完整示例
2020/03/29 Javascript
Flexible.js可伸缩布局实现方法详解
2020/11/13 Javascript
[01:13]这,就是刀塔
2014/07/16 DOTA
Django项目中实现使用qq第三方登录功能
2019/08/13 Python
Python @property使用方法解析
2019/09/17 Python
Python 生成器,迭代,yield关键字,send()传参给yield语句操作示例
2019/10/12 Python
Pytorch 实现focal_loss 多类别和二分类示例
2020/01/14 Python
TensorFlow通过文件名/文件夹名获取标签,并加入队列的实现
2020/02/17 Python
使用keras时input_shape的维度表示问题说明
2020/06/29 Python
使用Python项目生成所有依赖包的清单方式
2020/07/13 Python
Moda Operandi官网:美国奢侈品电商,海淘秀场T台同款
2020/05/26 全球购物
程序员机试试题汇总
2012/03/07 面试题
C#公司笔试题
2014/03/28 面试题
承认错误的检讨书
2014/01/30 职场文书
大学生个人自荐信
2014/02/24 职场文书
条幅标语大全
2014/06/20 职场文书
参观监狱警示教育心得体会
2016/01/15 职场文书