需要将某个网络端口转发到另外一个主机(forwarding),但可能会是不同的端口(redirecting)
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): 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): 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) 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 forwarder/redirector' import sys 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) #begin to work sys.stdout = open('pinhole.log','w') Pinhole(port, newhost, newport).start()
#python redirectport.py 8000 localhost 80
Sat Aug 25 08:38:55 2012:Creating new session for 127.0.0.1:49618
Sat Aug 25 08:38:55 2012:Creating new pipe thread <PipeThread(Thread-16, initial)> ( ('127.0.0.1', 49618) -> ('127.0.0.1', 80))
Sat Aug 25 08:38:55 2012:3 pipes now active
Sat Aug 25 08:38:55 2012:Creating new pipe thread <PipeThread(Thread-17, initial)> ( ('127.0.0.1', 80) -> ('127.0.0.1', 49618))
Sat Aug 25 08:38:55 2012:4 pipes now active
Sat Aug 25 08:38:55 2012:Creating new session for 127.0.0.1:49619
Sat Aug 25 08:38:55 2012:Creating new pipe thread <PipeThread(Thread-18, initial)> ( ('127.0.0.1', 49619) -> ('127.0.0.1', 80))
Sat Aug 25 08:38:55 2012:5 pipes now active
Sat Aug 25 08:38:55 2012:Creating new pipe thread <PipeThread(Thread-19, initial)> ( ('127.0.0.1', 80) -> ('127.0.0.1', 49619))
Sat Aug 25 08:38:55 2012:6 pipes now active
Sat Aug 25 08:39:08 2012:<PipeThread(Thread-17, started 140323525043968)> terminating
Sat Aug 25 08:39:08 2012:5 pipes still active
Sat Aug 25 08:39:09 2012:<PipeThread(Thread-19, started 140323550222080)> terminating
Sat Aug 25 08:39:09 2012:4 pipes still active
Sat Aug 25 08:39:10 2012:<PipeThread(Thread-18, started 140323541829376)> terminating
Sat Aug 25 08:39:10 2012:3 pipes still active
Sat Aug 25 08:39:10 2012:<PipeThread(Thread-16, started 140323592185600)> terminating
Sat Aug 25 08:39:10 2012:2 pipes still active