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使用minidom读写xml的方法
Jun 03 Python
python list排序的两种方法及实例讲解
Mar 20 Python
Python numpy实现数组合并实例(vstack,hstack)
Jan 09 Python
Python实现识别手写数字 Python图片读入与处理
Mar 23 Python
Python第三方Window模块文件的几种安装方法
Nov 22 Python
python requests post多层字典的方法
Dec 27 Python
python生成器用法实例详解
Nov 22 Python
Python捕获异常堆栈信息的几种方法(小结)
May 18 Python
Python分类测试代码实例汇总
Jul 23 Python
零基础学python应该从哪里入手
Aug 11 Python
python zip()函数的使用示例
Sep 23 Python
python 邮件检测工具mmpi的使用
Jan 04 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
E路文章系统PHP
2006/12/11 PHP
分页详解 从此分页无忧(PHP+mysql)
2007/11/23 PHP
基于Snoopy的PHP近似完美获取网站编码的代码
2011/10/23 PHP
PHP设置一边执行一边输出结果的代码
2013/09/30 PHP
PHP使用CURL模拟登录的方法
2015/07/08 PHP
详解WordPress中创建和添加过滤器的相关PHP函数
2015/12/29 PHP
thinkPHP中volist标签用法示例
2016/12/06 PHP
为何说PHP引用是个坑,要慎用
2018/04/02 PHP
PHP设计模式之数据访问对象模式(DAO)原理与用法实例分析
2019/12/12 PHP
js获取当前日期代码适用于网页头部
2013/06/27 Javascript
javascript实现单击和双击并存的方法
2014/12/13 Javascript
jquery 实现输入邮箱时自动补全下拉提示功能
2015/10/04 Javascript
CSS或者JS实现鼠标悬停显示另一元素
2016/01/22 Javascript
AngularJS基础 ng-submit 指令简单示例
2016/08/03 Javascript
js HTML5手机刮刮乐代码
2020/09/29 Javascript
浅谈AngularJs指令之scope属性详解
2016/10/24 Javascript
修改UA在PC中访问只能在微信中打开的链接方法
2017/11/27 Javascript
微信小程序onShareTimeline()实现分享朋友圈
2021/01/07 Javascript
[01:35]辉夜杯战队访谈宣传片—LGD
2015/12/25 DOTA
Python键盘输入转换为列表的实例
2018/06/23 Python
对python3 sort sorted 函数的应用详解
2019/06/27 Python
Python爬虫使用浏览器cookies:browsercookie过程解析
2019/10/22 Python
python爬虫模拟浏览器访问-User-Agent过程解析
2019/12/28 Python
Python使用lambda抛出异常实现方法解析
2020/08/20 Python
浅析Python 责任链设计模式
2020/09/11 Python
理肤泉俄罗斯官网:La Roche-Posay俄罗斯
2018/07/24 全球购物
屈臣氏俄罗斯在线商店:Watsons俄罗斯
2020/08/03 全球购物
通信工程专业毕业生推荐信
2013/12/25 职场文书
大学生职业生涯规划书模版
2013/12/30 职场文书
银行职员自我鉴定
2014/04/20 职场文书
小学生竞选班干部演讲稿
2014/04/24 职场文书
2014年秋季开学典礼主持词
2014/08/02 职场文书
谢师宴家长答谢词
2015/09/30 职场文书
go语言map与string的相互转换的实现
2021/04/07 Golang
HTML速写之Emmet语法规则的实现
2021/04/07 HTML / CSS
MongoDB支持的数据类型
2022/04/11 MongoDB