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的汉字转GBK码实现代码
Feb 19 Python
pygame学习笔记(6):完成一个简单的游戏
Apr 15 Python
Python编程之变量赋值操作实例分析
Jul 24 Python
python中 logging的使用详解
Oct 25 Python
Java分治归并排序算法实例详解
Dec 12 Python
Django实战之用户认证(初始配置)
Jul 16 Python
浅谈Python traceback的优雅处理
Aug 31 Python
Python实现的拉格朗日插值法示例
Jan 08 Python
详解pandas中MultiIndex和对象实际索引不一致问题
Jul 23 Python
opencv转换颜色空间更改图片背景
Aug 20 Python
在Python中利用pickle保存变量的实例
Dec 30 Python
用PYTHON去计算88键钢琴的琴键频率和音高
Apr 10 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设计模式 Composite (组合模式)
2011/06/26 PHP
php三维数组去重(示例代码)
2013/11/26 PHP
PHP 正则表达式小结
2015/02/12 PHP
php结合redis高并发下发帖、发微博的实现方法
2016/12/15 PHP
利用Ext Js生成动态树实例代码
2008/09/08 Javascript
javascript中最常用的继承模式 组合继承
2010/08/12 Javascript
根据表格中的某一列进行排序的javascript代码
2013/11/29 Javascript
搭建pomelo 开发环境
2014/06/24 Javascript
Javascript基础教程之数据类型转换
2015/01/18 Javascript
javascript自定义in_array()函数实现方法
2015/08/03 Javascript
BootStrap入门教程(一)之可视化布局
2016/09/19 Javascript
JavaScript递归操作实例浅析
2016/10/31 Javascript
JS设置随机出现2个数字的实例代码
2017/07/19 Javascript
JS原生轮播图的简单实现(推荐)
2017/07/22 Javascript
微信小程序实现的点击按钮 弹出底部上拉菜单功能示例
2018/12/20 Javascript
create-react-app使用antd按需加载的样式无效问题的解决
2019/02/26 Javascript
React组件设计模式之组合组件应用实例分析
2020/04/29 Javascript
返回上一个url并刷新界面的js代码
2020/09/12 Javascript
再也不怕 JavaScript 报错了,怎么看怎么处理都在这儿
2020/12/09 Javascript
Python的Tornado框架实现图片上传及图片大小修改功能
2016/06/30 Python
PYTHON 中使用 GLOBAL引发的一系列问题
2016/10/12 Python
英国泰坦旅游网站:全球陪同游览,邮轮和铁路旅行
2016/11/29 全球购物
日本必酷网络直营店:Biccamera
2019/03/23 全球购物
汉米尔顿手表官网:Hamilton
2020/09/13 全球购物
Java和Javasciprt的区别
2012/09/02 面试题
历史学专业个人的自我评价
2013/10/13 职场文书
简历中个人求职的自我评价模板
2013/11/29 职场文书
四查四看剖析材料
2014/02/14 职场文书
人民调解员先进事迹材料
2014/05/08 职场文书
客户经理竞聘演讲稿
2014/05/15 职场文书
组工干部对照检查材料
2014/08/25 职场文书
区政府领导班子个人对照检查材料
2014/09/25 职场文书
2014年城市管理工作总结
2014/12/02 职场文书
2015年科协工作总结
2015/05/19 职场文书
全家福照片寄语怎么写?
2019/04/02 职场文书
python自动统计zabbix系统监控覆盖率的示例代码
2021/04/03 Python