本文實例講述了Python實現網絡端口轉發和重定向的方法。分享給大家供大家參考,具體如下:
【任務】
需要將某個網絡端口轉發到另一個主機(forwarding),但可能會是不同的端口(redirecting)。
【解決方案】
兩個使用threading和socket模塊的類就能完成我們需要的端口轉發和重定向。
#encoding=utf8#author: walker摘自《Python Cookbook(2rd)》#date: 2015-06-11#function: 網絡端口的轉發和重定向(適用于python2/python3)import sys, socket, time, threadingLOGGING = Trueloglock = 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程序設計有所幫助。
新聞熱點
疑難解答