English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Python으로 네트워크 포트 포워딩 및 리디렉션 방법 구현

이 문서는 Python을 통해 네트워크 포트 포워딩과 리디렉션 방법을 설명합니다. 여러분과 공유하고, 자세한 내용은 다음과 같습니다:

【업무】

어떤 네트워크 포트를 다른 호스트로 전송할 필요가 있지만, 다른 포트로도 가능할 수 있습니다(전송).

【해결책】

두 개의 threading과 socket 모듈을 사용하는 클래스로 필요한 포트 전송 및 재정리를 수행할 수 있습니다.

#encoding=utf8
#author: walker摘自《Python Cookbook(2rd)》
#date: 2015-06-11
#function: 네트워크 포트의 전송 및 재정리(Python에 적용)2/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('사용법: %s port newhost [newport]' % sys.argv[0])
    sys.exit(1)
  #sys.stdout = open('pinhole.log', 'w') # 로그를 파일에 쓰기
  Pinhole(port, newhost, newport).start()

【논의】

네트워크를 관리하는 동안, 매우 작은 네트워크라도 포트 전환 및 리디렉션 기능이 때로는 큰 도움이 될 수 있습니다. 여러분의 제어를 벗어난 애플리케이션이나 서비스는 특정 서버의 주소나 포트에 단정한 연결 방식으로 연결되어 있을 수 있습니다. 전환 및 리디렉션을 삽입하여, 애플리케이션의 연결 요청을 더 적합한 호스트나 포트로 전송할 수 있습니다.

Python 관련 내용에 더 많은 관심을 가지고 계신 독자는 다음 주제를 확인할 수 있습니다:《Python URL 작업 기술 요약》、《Python Socket 프로그래밍 기술 요약》、《Python 이미지 작업 기술 요약》、《Python 데이터 구조 및 알고리즘 교본》、《Python 함수 사용 기술 요약》、《Python 문자열 작업 요약》、《Python 입문 및 중급 교본》 및 《Python 파일 및 디렉토리 작업 기술 요약》

이 문서에서 설명된 내용이 여러분의 Python 프로그래밍에 도움이 되길 바랍니다.

선언: 이 문서의 내용은 인터넷에서 가져왔으며, 저작권은 원작자에게 있으며, 인터넷 사용자가 자발적으로 기여하고 업로드한 내용입니다. 이 사이트는 소유권을 가지지 않으며, 인공 편집을 하지 않았으며, 관련 법적 책임도 부담하지 않습니다. 저작권 위반이 의심되는 내용을 발견하면, notice#w로 이메일을 보내 주세요.3codebox.com(이메일을 보내면, #을 @으로 변경해 주세요. 신고하고 관련 증거를 제공하시면, 실제로 확인되면, 이 사이트는 즉시 저작권 위반 내용을 삭제합니다。)

당신이 좋아할 만한 것