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实现从字符串中找出字符1的位置以及个数的方法
Aug 25 Python
Python实现把回车符\r\n转换成\n
Apr 23 Python
浅析Python中元祖、列表和字典的区别
Aug 17 Python
Python连接DB2数据库
Aug 27 Python
python tkinter界面居中显示的方法
Oct 11 Python
python 实现得到当前时间偏移day天后的日期方法
Dec 31 Python
执行Django数据迁移时报 1091错误及解决方法
Oct 14 Python
如何获取Python简单for循环索引
Nov 21 Python
解决pytorch报错:AssertionError: Invalid device id的问题
Jan 10 Python
使用Keras实现简单线性回归模型操作
Jun 12 Python
python 制作python包,封装成可用模块教程
Jul 13 Python
python zip()函数的使用示例
Sep 23 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
9段PHP实用功能的代码推荐
2014/10/14 PHP
php中字符查找函数strpos、strrchr与strpbrk用法
2014/11/18 PHP
php在apache环境下实现gzip配置方法
2015/04/02 PHP
PHP实现全角字符转为半角方法汇总
2015/07/09 PHP
thinkPHP微信分享接口JSSDK用法实例
2017/07/07 PHP
PHP7生产环境队列Beanstalkd用法详解
2020/05/19 PHP
浅析ajax请求json数据并用js解析(示例分析)
2013/07/13 Javascript
js 文本滚动效果的实例代码
2013/08/17 Javascript
jquery下div 的resize事件示例代码
2014/03/09 Javascript
jQuery实现dialog设置focus焦点的方法
2015/06/10 Javascript
浅析angularJS中的ui-router和ng-grid模块
2016/05/20 Javascript
Bootstrap 3.x打印预览背景色与文字显示异常的解决
2016/11/06 Javascript
js实现省份下拉菜单效果
2017/02/15 Javascript
JS设置手机验证码60s等待实现代码
2017/06/14 Javascript
10分钟上手vue-cli 3.0 入门介绍
2018/04/04 Javascript
浅谈express.js框架中间件(middleware)
2019/04/07 Javascript
纯javascript实现选择框的全选与反选功能
2019/04/08 Javascript
使用layer模态框给新页面传值的方法
2019/09/27 Javascript
vue实现表格合并功能
2020/12/01 Vue.js
vue监听滚动事件的方法
2020/12/21 Vue.js
python采用requests库模拟登录和抓取数据的简单示例
2014/07/05 Python
python多线程编程中的join函数使用心得
2014/09/02 Python
Python 3.6 读取并操作文件内容的实例
2018/04/23 Python
python提取包含关键字的整行数据方法
2018/12/11 Python
Python3利用Dlib实现摄像头实时人脸检测和平铺显示示例
2019/02/21 Python
Python 批量读取文件中指定字符的实现
2020/03/06 Python
Numpy一维线性插值函数的用法
2020/04/22 Python
Python小白不正确的使用类变量实例
2020/05/29 Python
canvas实现飞机打怪兽射击小游戏的示例代码
2018/07/09 HTML / CSS
Mountain Warehouse德国官网:英国户外零售商
2019/08/11 全球购物
百度软件工程师职位
2013/02/14 面试题
什么是Remote Module
2016/06/10 面试题
研修第一天随笔感言
2014/02/15 职场文书
构建高效课堂实施方案
2014/03/13 职场文书
服务承诺书格式
2014/05/21 职场文书
ROS系统将python包编译为可执行文件的简单步骤
2021/07/25 Python