ホームページ > バックエンド開発 > Python チュートリアル > Python でネットワーク ポート転送とリダイレクトを実装する方法

Python でネットワーク ポート転送とリダイレクトを実装する方法

高洛峰
リリース: 2017-02-15 14:36:27
オリジナル
2528 人が閲覧しました

この記事の例では、Python でネットワーク ポート転送とリダイレクトを実装する方法を説明します。参考のために皆さんと共有してください。詳細は次のとおりです:

[タスク]

特定のネットワーク ポートを別のホストに転送する必要がありますが (フォワーディング)、別のポートである可能性があります (リダイレクト)。

【解決策】

スレッドモジュールとソケットモジュールを使用する 2 つのクラスで、必要なポート転送とリダイレクトを完了できます。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

#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 がネットワーク ポート転送とリダイレクトを実装する方法に関するその他の関連記事については、PHP 中国語 Web サイトに注目してください。

関連ラベル:
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート