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 相关文章推荐
一个基于flask的web应用诞生 使用模板引擎和表单插件(2)
Apr 11 Python
对pandas中apply函数的用法详解
Apr 10 Python
python验证码识别教程之利用投影法、连通域法分割图片
Jun 04 Python
无法使用pip命令安装python第三方库的原因及解决方法
Jun 12 Python
python使用mitmproxy抓取浏览器请求的方法
Jul 02 Python
Django 权限认证(根据不同的用户,设置不同的显示和访问权限)
Jul 24 Python
python实现知乎高颜值图片爬取
Aug 12 Python
python框架Django实战商城项目之工程搭建过程图文详解
Mar 09 Python
Python爬虫程序架构和运行流程原理解析
Mar 09 Python
Python实现电视里的5毛特效实例代码详解
May 15 Python
如何卸载python插件
Jul 08 Python
Python hashlib模块的使用示例
Oct 09 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
受疫情影响 动画《Re从零开始的异世界生活》第二季延期至7月
2020/03/10 日漫
php递归列出所有文件和目录的代码
2008/09/10 PHP
PHP的加密方式及原理
2012/06/14 PHP
PHP常用的文件操作函数经典收藏
2013/04/02 PHP
yii操作cookie实例简介
2014/07/09 PHP
PHP微信公众号开发之微信红包实现方法分析
2017/07/14 PHP
PHP文件管理之实现网盘及压缩包的功能操作
2017/09/20 PHP
PHP快速导出百万级数据到CSV或者EXCEL文件
2020/11/27 PHP
$.format,jquery.format 使用说明
2011/07/13 Javascript
SyntaxHighlighter 3.0.83使用笔记
2015/01/26 Javascript
JavaScript数组方法总结分析
2016/05/06 Javascript
详解基于javascript实现的苹果系统底部菜单
2016/12/02 Javascript
Input文本框随着输入内容多少自动延伸的实现
2017/02/15 Javascript
React 实现车牌键盘的示例代码
2019/12/20 Javascript
JavaScript实现联动菜单特效
2020/01/07 Javascript
Vue页面手动刷新,实现导航栏激活项还原到初始状态
2020/08/06 Javascript
React Native登录之指纹登录篇的示例代码
2020/11/03 Javascript
详解ES6 扩展运算符的使用与注意事项
2020/11/12 Javascript
[45:52]完美世界DOTA2联赛PWL S3 Forest vs INK ICE 第二场 12.09
2020/12/12 DOTA
python使用PIL缩放网络图片并保存的方法
2015/04/24 Python
Python3.4实现从HTTP代理网站批量获取代理并筛选的方法示例
2017/09/26 Python
python Celery定时任务的示例
2018/03/13 Python
Python异常处理例题整理
2019/07/07 Python
python2.7实现复制大量文件及文件夹资料
2019/08/31 Python
Python如何使用BeautifulSoup爬取网页信息
2019/11/26 Python
Python+OpenCV实现将图像转换为二进制格式
2020/01/09 Python
Python装饰器用法与知识点小结
2020/03/09 Python
解决Keras中CNN输入维度报错问题
2020/06/29 Python
国际领先的在线时尚服装和配饰店:DressLily
2019/03/03 全球购物
澳大利亚领先的武术用品和健身器材供应商:SMAI
2019/03/24 全球购物
CK澳大利亚官网:Calvin Klein澳大利亚
2020/12/12 全球购物
网络方面基础面试题
2012/11/16 面试题
工程造价与财务管理专业应届生求职信
2013/10/06 职场文书
集团公司总经理岗位职责
2013/12/20 职场文书
教学实习自我评价
2014/01/28 职场文书
考研经验交流会策划书
2015/11/02 职场文书