Python端口转发小脚本

非异步

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import socket
import threading
import logging
import optparse


class PipeThread(threading.Thread):

    def __init__(self, source_fd, target_fd):
        super(PipeThread, self).__init__()
        self.logger = logging.getLogger('PipeThread')
        self.source_fd = source_fd
        self.target_fd = target_fd
        self.source_addr = self.source_fd.getpeername()
        self.target_addr = self.target_fd.getpeername()

    def run(self):
        while True:
            try:
                data = self.source_fd.recv(4096)
                if len(data) > 0:
                    self.logger.debug('read  %04i from %s:%d', len(data),
                                      self.source_addr[0], self.source_addr[1])
                    sent = self.target_fd.send(data)
                    self.logger.debug('write %04i to   %s:%d', sent,
                                      self.target_addr[0], self.target_addr[1])
                else:
                    break
            except socket.error:
                break
        self.logger.debug('connection %s:%d is closed.', self.source_addr[0],
                          self.source_addr[1])
        self.logger.debug('connection %s:%d is closed.', self.target_addr[0],
                          self.target_addr[1])
        self.source_fd.close()
        self.target_fd.close()


class Forwarder(object):

    def __init__(self, ip, port, remoteip, remoteport, backlog=5):
        self.remoteip = remoteip
        self.remoteport = remoteport
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind((ip, port))
        self.sock.listen(backlog)

    def run(self):
        while True:
            client_fd, client_addr = self.sock.accept()
            target_fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            target_fd.connect((self.remoteip, self.remoteport))

            threads = [
                PipeThread(client_fd, target_fd),
                PipeThread(target_fd, client_fd)
            ]

            for t in threads:
                t.setDaemon(True)
                t.start()

    def __del__(self):
        self.sock.close()


def main():
    parser = optparse.OptionParser()

    parser.add_option(
        '-l', '--local-ip', dest='local_ip',
        help='Local IP address to bind to')
    parser.add_option(
        '-p', '--local-port',
        type='int', dest='local_port',
        help='Local port to bind to')
    parser.add_option(
        '-r', '--remote-ip', dest='remote_ip',
        help='Local IP address to bind to')
    parser.add_option(
        '-P', '--remote-port',
        type='int', dest='remote_port',
        help='Remote port to bind to')
    parser.add_option(
        '-v', '--verbose',
        action='store_true', dest='verbose',
        help='verbose')
    opts, args = parser.parse_args()

    if len(sys.argv) == 1 or len(args) > 0:
        parser.print_help()
        exit()

    if not (opts.local_ip and opts.local_port and opts.remote_ip and opts.remote_port):
        parser.print_help()
        exit()

    if opts.verbose:
        log_level = logging.DEBUG
    else:
        log_level = logging.CRITICAL

    logging.basicConfig(level=log_level, format='%(name)-11s: %(message)s')
    forwarder = Forwarder(opts.local_ip, opts.local_port, opts.remote_ip, opts.remote_port)

    try:
        forwarder.run()
    except KeyboardInterrupt:
        print 'quit'
        exit()


if __name__ == '__main__':
    main()

异步

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import socket
import asyncore
import logging
import optparse


class Forwarder(asyncore.dispatcher):

    def __init__(self, ip, port, remoteip, remoteport, backlog=5):
        asyncore.dispatcher.__init__(self)
        self.remoteip = remoteip
        self.remoteport = remoteport
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind((ip, port))
        self.listen(backlog)

    def handle_accept(self):
        conn, addr = self.accept()
        Sender(Receiver(conn), self.remoteip, self.remoteport)


class Receiver(asyncore.dispatcher):

    def __init__(self, conn):
        asyncore.dispatcher.__init__(self, conn)
        self.logger = logging.getLogger('Receiver')
        self.clientaddr, self.clientport = conn.getpeername()
        self.from_client_buffer = ''
        self.to_client_buffer = ''
        self.Sender = None

    def handle_connect(self):
        pass

    def handle_read(self):
        read = self.recv(4096)
        if len(read) > 0:
            self.logger.debug('read  %04i --> from %s:%d', len(read), self.clientaddr, self.clientport)
            self.from_client_buffer += read

    def writable(self):
        return len(self.to_client_buffer) > 0

    def handle_write(self):
        sent = self.send(self.to_client_buffer)
        self.logger.debug('write %04i <-- to   %s:%d', sent, self.clientaddr, self.clientport)
        self.to_client_buffer = self.to_client_buffer[sent:]

    def handle_close(self):
        self.close()
        if self.Sender:
            self.Sender.close()


class Sender(asyncore.dispatcher):

    def __init__(self, Receiver, remoteaddr, remoteport):
        asyncore.dispatcher.__init__(self)
        self.logger = logging.getLogger('Sender')
        self.remoteaddr = remoteaddr
        self.remoteport = remoteport
        self.Receiver = Receiver
        Receiver.Sender = self
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect((remoteaddr, remoteport))

    def handle_connect(self):
        pass

    def handle_read(self):
        read = self.recv(4096)
        if len(read) > 0:
            self.logger.debug('read  <-- %04i from %s:%d', len(read), self.remoteaddr, self.remoteport)
            self.Receiver.to_client_buffer += read

    def writable(self):
        return len(self.Receiver.from_client_buffer) > 0

    def handle_write(self):
        sent = self.send(self.Receiver.from_client_buffer)
        self.logger.debug('write --> %04i to   %s:%d', sent, self.remoteaddr, self.remoteport)
        self.Receiver.from_client_buffer = self.Receiver.from_client_buffer[sent:]

    def handle_close(self):
        self.close()
        self.Receiver.close()


def main():
    parser = optparse.OptionParser()

    parser.add_option(
        '-l', '--local-ip', dest='local_ip',
        help='Local IP address to bind to')
    parser.add_option(
        '-p', '--local-port',
        type='int', dest='local_port',
        help='Local port to bind to')
    parser.add_option(
        '-r', '--remote-ip', dest='remote_ip',
        help='Local IP address to bind to')
    parser.add_option(
        '-P', '--remote-port',
        type='int', dest='remote_port',
        help='Remote port to bind to')
    parser.add_option(
        '-v', '--verbose',
        action='store_true', dest='verbose',
        help='verbose')
    opts, args = parser.parse_args()

    if len(sys.argv) == 1 or len(args) > 0:
        parser.print_help()
        exit()

    if not (opts.local_ip and opts.local_port and opts.remote_ip and opts.remote_port):
        parser.print_help()
        exit()

    if opts.verbose:
        log_level = logging.DEBUG
    else:
        log_level = logging.CRITICAL

    logging.basicConfig(level=log_level, format='%(name)-9s: %(message)s')
    Forwarder(opts.local_ip, opts.local_port, opts.remote_ip, opts.remote_port)

    try:
        asyncore.loop(use_poll=True)
    except KeyboardInterrupt:
        print 'quit'
        exit()


if __name__ == '__main__':
    main()


你可能感兴趣的:(python)