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读取浮点数和读取文本文件示例
May 06 Python
Python中使用haystack实现django全文检索搜索引擎功能
Aug 26 Python
Django 连接sql server数据库的方法
Jun 30 Python
python 异或加密字符串的实例
Oct 14 Python
django解决跨域请求的问题
Nov 11 Python
Python中函数的基本定义与调用及内置函数详解
May 13 Python
python并发编程多进程 互斥锁原理解析
Aug 20 Python
利用pandas合并多个excel的方法示例
Oct 10 Python
Python 类,property属性(简化属性的操作),@property,property()用法示例
Oct 12 Python
python主线程与子线程的结束顺序实例解析
Dec 17 Python
浅谈keras中的后端backend及其相关函数(K.prod,K.cast)
Jun 29 Python
通过实例解析Python RPC实现原理及方法
Jul 07 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反射使用实例和PHP反射API的中文说明
2014/07/02 PHP
PHP5.3新特性小结
2016/02/14 PHP
Laravel的Auth验证Token验证使用自定义Redis的例子
2019/09/30 PHP
js数据验证集合、js email验证、js url验证、js长度验证、js数字验证等简单封装
2010/05/15 Javascript
javascript对数组的常用操作代码 数组方法总汇
2011/01/27 Javascript
用js调用迅雷下载代码的二种方法
2013/04/15 Javascript
jQuery中选择器小问题(新人难免遇到)
2014/03/31 Javascript
jQuery实现dialog设置focus焦点的方法
2015/06/10 Javascript
认识Knockout及如何使用Knockout绑定上下文
2015/12/25 Javascript
理解javascript中的严格模式
2016/02/01 Javascript
JavaScript中的操作符类型转换示例总结
2016/05/30 Javascript
Bootstrap开发实战之响应式轮播图
2016/06/02 Javascript
浅谈jquery的html方法里包含特殊字符的处理
2016/11/30 Javascript
js实现抽奖效果
2017/03/27 Javascript
JavaScript中this的用法及this在不同应用场景的作用解析
2017/04/13 Javascript
js es6系列教程 - 基于new.target属性与es5改造es6的类语法
2017/09/02 Javascript
Vue解析剪切板图片并实现发送功能
2020/02/04 Javascript
js+css实现扇形导航效果
2020/08/18 Javascript
[05:53]敌法师的金色冠名ID"BurNIng",是传说,是荣耀
2020/07/11 DOTA
python Django框架实现自定义表单提交
2016/03/25 Python
Python使用urllib2模块抓取HTML页面资源的实例分享
2016/05/03 Python
windows及linux环境下永久修改pip镜像源的方法
2016/11/28 Python
node.js获取参数的常用方法(总结)
2017/05/29 Python
python实现可视化动态CPU性能监控
2018/06/21 Python
Django上使用数据可视化利器Bokeh解析
2019/07/31 Python
keras中的loss、optimizer、metrics用法
2020/06/15 Python
python 基于opencv 绘制图像轮廓
2020/12/11 Python
详解css3 Transition属性(平滑过渡菜单栏案例)
2017/09/05 HTML / CSS
使用html2canvas实现浏览器截图的示例代码
2018/01/26 HTML / CSS
利用HTML5 Canvas制作一个简单的打飞机游戏
2015/05/11 HTML / CSS
印尼太阳百货公司网站:Matahari
2018/02/04 全球购物
学前教育学生自荐信范文
2013/12/31 职场文书
捐书活动总结
2014/05/04 职场文书
宪法宣传周工作方案
2014/05/26 职场文书
创业计划书之花店
2019/09/20 职场文书
Winsows11性能如何? win11性能测评多核竟比Win10差了10%
2021/11/21 数码科技