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 相关文章推荐
Pyramid添加Middleware的方法实例
Nov 27 Python
简单介绍Python2.x版本中的cmp()方法的使用
May 20 Python
python机器学习实战之树回归详解
Dec 20 Python
python实现数据写入excel表格
Mar 25 Python
Python实现的简单计算器功能详解
Aug 25 Python
解决Python3.5+OpenCV3.2读取图像的问题
Dec 05 Python
Django项目中实现使用qq第三方登录功能
Aug 13 Python
python fuzzywuzzy模块模糊字符串匹配详细用法
Aug 29 Python
pytorch1.0中torch.nn.Conv2d用法详解
Jan 10 Python
Python修改列表值问题解决方案
Mar 06 Python
python使用多线程+socket实现端口扫描
May 28 Python
Opencv实现二维直方图的计算及绘制
Jul 21 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计算上一个月的今天
2013/05/23 PHP
yii2 RBAC使用DbManager实现后台权限判断的方法
2016/07/23 PHP
PC端微信扫码支付成功之后自动跳转php版代码
2017/07/07 PHP
Laravel中七个非常有用但很少人知道的Carbon方法
2017/09/21 PHP
70+漂亮且极具亲和力的导航菜单设计国外网站推荐
2011/09/20 Javascript
JavaScript中的对象继承关系
2016/08/01 Javascript
将form表单通过ajax实现无刷新提交的简单实例
2016/10/12 Javascript
ES2015 Symbol 一种绝不重复的值
2016/12/25 Javascript
js 动态生成html 触发事件传参字符转义的实例
2017/02/14 Javascript
JavaScript实现星星等级评价功能
2017/03/22 Javascript
javascript基于定时器实现进度条功能实例
2017/10/13 Javascript
详解Vue2 SSR 缓存 Api 数据
2017/11/20 Javascript
微信小程序利用swiper+css实现购物车商品删除功能
2019/03/06 Javascript
小程序组件之自定义顶部导航实例
2019/06/12 Javascript
javascript中layim之查找好友查找群组
2021/02/06 Javascript
Django中redis的使用方法(包括安装、配置、启动)
2018/02/21 Python
解决python3 pika之连接断开的问题
2018/12/18 Python
python语言基本语句用法总结
2019/06/11 Python
Python企业编码生成系统之主程序模块设计详解
2019/07/26 Python
关于keras.layers.Conv1D的kernel_size参数使用介绍
2020/05/22 Python
Html5 audio标签样式的修改
2016/01/28 HTML / CSS
ProBikeKit美国官网:自行车套件,跑步和铁人三项套件
2016/10/13 全球购物
史蒂夫·马登加拿大官网:Steve Madden加拿大
2017/11/18 全球购物
美国最流行的男士时尚网站:Touch of Modern
2018/02/05 全球购物
Wiggle澳大利亚:自行车、跑步、游泳商店
2020/11/07 全球购物
酒店员工检讨书
2014/02/18 职场文书
卖房协议书
2014/04/11 职场文书
《望庐山瀑布》教学反思
2014/04/22 职场文书
小学生倡议书范文
2014/05/13 职场文书
中层干部培训方案
2014/06/16 职场文书
师范毕业生求职信
2014/07/11 职场文书
2014年节能降耗工作总结
2014/12/11 职场文书
就业意向协议书
2015/01/29 职场文书
财务工作失误检讨书
2015/02/19 职场文书
广告策划的实习心得体会总结!
2019/07/22 职场文书
go 原生http web 服务跨域restful api的写法介绍
2021/04/27 Golang