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打包可执行文件的方法详解
Sep 19 Python
python中装饰器级连的使用方法示例
Sep 29 Python
Python语言生成水仙花数代码示例
Dec 18 Python
python机器学习之神经网络(三)
Dec 20 Python
详解tensorflow实现迁移学习实例
Feb 10 Python
对pandas中to_dict的用法详解
Jun 05 Python
numpy.ndarray 交换多维数组(矩阵)的行/列方法
Aug 02 Python
Flask实现跨域请求的处理方法
Sep 27 Python
python解析含有重复key的json方法
Jan 22 Python
python多线程扫描端口(线程池)
Sep 04 Python
Python绘制K线图之可视化神器pyecharts的使用
Mar 02 Python
pytorch实现ResNet结构的实例代码
May 17 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
PHP查询网站的PR值
2013/10/30 PHP
php Imagick获取图片RGB颜色值
2014/07/28 PHP
ThinkPHP自动填充实现无限级分类的方法
2014/08/22 PHP
Yii2 队列 shmilyzxt/yii2-queue 简单概述
2017/08/02 PHP
PHP面向对象五大原则之依赖倒置原则(DIP)详解
2018/04/08 PHP
特殊字符、常规符号及其代码对照表
2006/06/26 Javascript
js 函数调用模式小结
2011/12/26 Javascript
JQuery实现倒计时按钮具体方法
2013/11/14 Javascript
js中Math之random,round,ceil,floor的用法总结
2013/12/26 Javascript
JS中表单的使用小结
2014/01/11 Javascript
深入理解javascript严格模式(Strict Mode)
2014/11/28 Javascript
jquery实现图片放大镜功能
2015/11/23 Javascript
JavaScript程序设计之JS调试
2015/12/09 Javascript
功能强大的Bootstrap组件(结合js)
2016/08/03 Javascript
基于JavaScript实现熔岩灯效果导航菜单
2017/01/04 Javascript
angular2组件中定时刷新并清除定时器的实例讲解
2018/08/31 Javascript
vue ssr+koa2构建服务端渲染的示例代码
2020/03/23 Javascript
Vue如何基于es6导入外部js文件
2020/05/15 Javascript
Python 稀疏矩阵-sparse 存储和转换
2017/05/27 Python
神经网络相关之基础概念的讲解
2018/12/29 Python
基于python3 pyQt5 QtDesignner实现窗口化猜数字游戏功能
2019/07/15 Python
Python自动化完成tb喵币任务的操作方法
2019/10/30 Python
在tensorflow中实现屏蔽输出的log信息
2020/02/04 Python
pyinstaller将含有多个py文件的python程序做成exe
2020/04/29 Python
详解如何解决canvas图片getImageData,toDataURL跨域问题
2018/09/17 HTML / CSS
html table呈现个人简历以及单元格宽度失效的问题解决
2021/01/22 HTML / CSS
英国文具、办公用品和科技商店:Ryman
2018/09/27 全球购物
后勤工作职责
2013/12/22 职场文书
政风行风评议工作总结
2014/10/21 职场文书
2014年干部作风建设总结
2014/10/23 职场文书
2014年安全管理工作总结
2014/12/01 职场文书
区域销售经理岗位职责
2015/04/02 职场文书
2015七夕情人节宣传语
2015/07/14 职场文书
欢送领导祝酒词
2015/08/12 职场文书
Feign调用全局异常处理解决方案
2021/06/24 Java/Android
Python+DeOldify实现老照片上色功能
2022/06/21 Python