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 相关文章推荐
Python3基础之list列表实例解析
Aug 13 Python
Python中的赋值、浅拷贝、深拷贝介绍
Mar 09 Python
python获取从命令行输入数字的方法
Apr 29 Python
Python基于正则表达式实现文件内容替换的方法
Aug 30 Python
PyQt5打开文件对话框QFileDialog实例代码
Feb 07 Python
Python统计纯文本文件中英文单词出现个数的方法总结【测试可用】
Jul 25 Python
浅谈python函数调用返回两个或多个变量的方法
Jan 23 Python
python TF-IDF算法实现文本关键词提取
May 29 Python
Django如何自定义model创建数据库索引的顺序
Jun 20 Python
Mac PyCharm中的.gitignore 安装设置教程
Apr 16 Python
宝塔面板成功部署Django项目流程(图文)
Jun 22 Python
Python+unittest+DDT实现数据驱动测试
Nov 30 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 验证码实例代码
2010/06/01 PHP
深入php处理整数函数的详解
2013/06/09 PHP
PHP嵌套输出缓冲代码实例
2015/05/12 PHP
thinkphp实现图片上传功能
2016/01/13 PHP
深入解析PHP的Laravel框架中的event事件操作
2016/03/21 PHP
php中引用符号(&)的使用详细介绍
2016/12/06 PHP
PHP使用Redis替代文件存储Session的方法
2017/02/15 PHP
数理公式,也可以这么唯美
2021/03/10 无线电
你真的了解JavaScript吗?
2007/02/24 Javascript
Jquery Ajax 学习实例2 向页面发出请求 返回JSon格式数据
2010/03/15 Javascript
jQuery在vs2008及js文件中的无智能提示的解决方法
2010/12/30 Javascript
artdialog的图片/标题以及关闭按钮不显示的解决方法
2013/06/27 Javascript
json属性名为什么要双引号(个人猜测)
2014/07/31 Javascript
为什么Node.js会这么火呢?Node.js流行的原因
2014/12/01 Javascript
javascript中的遍历for in 以及with的用法
2014/12/22 Javascript
js限制文本框的输入内容代码分享(3类)
2015/08/20 Javascript
用canvas 实现个图片三角化(LOW POLY)效果
2016/02/18 Javascript
JS生成和下载二维码的代码
2016/12/07 Javascript
SpringMVC+bootstrap table实例详解
2017/06/02 Javascript
Vue.js路由实现选项卡简单实例
2019/07/24 Javascript
解决vue项目F5刷新mounted里的函数不执行问题
2019/11/05 Javascript
vue组件入门知识全梳理
2020/09/21 Javascript
[01:20]DOTA2更新全新英雄 天涯墨客现已加入游戏
2018/08/25 DOTA
python daemon守护进程实现
2016/08/27 Python
通过Python 接口使用OpenCV的方法
2018/04/02 Python
Python中字符串与编码示例代码
2019/05/20 Python
python单例模式原理与创建方法实例分析
2019/10/26 Python
python3爬取torrent种子链接实例
2020/01/16 Python
pytorch masked_fill报错的解决
2020/02/18 Python
python搜索算法原理及实例讲解
2020/11/18 Python
婚鞋、新娘鞋、礼服鞋、童鞋:Nina Shoes
2019/09/04 全球购物
文明餐桌行动实施方案
2014/02/19 职场文书
大学生党员学习焦裕禄精神思想汇报
2014/09/10 职场文书
小学教育见习总结
2015/06/23 职场文书
中国文明网2015年“向国旗敬礼”活动网上签名寄语
2015/09/24 职场文书
使用scrapy实现增量式爬取方式
2022/06/21 Python