python学习笔记:利用asyncore的端口映射(端口转发)

import asyncore
import socket
import sys


class Receiver(asyncore.dispatcher_with_send):
    
    def __init__(self,sock,remote_ip,remote_port):
        asyncore.dispatcher_with_send.__init__(self,sock=sock)
        self.buffer=""
        self.max_buffer_size=1024000
        self.remote_ip=remote_ip
        self.remote_port=remote_port
        sender_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        try:
            sender_sock.connect((self.remote_ip,self.remote_port))
            print 'connected to %s:%d' % (self.remote_ip,self.remote_port)
            self.sender=Sender(self,sender_sock)
        except Exception,e:
            print e
            self.close()
        
       
    def handle_read(self):
        data = self.recv(10240)
        if data:
            try:
                self.sender.sendall(data)
                print '%4d bytes' % sys.getsizeof(data)
            except Exception, e:
                print e

    def handle_close(self):
        print "closing receiver..."
        try:
            self.close()
            self.sender.close()

        except Exception, e:
            print e
        
        
class Sender(asyncore.dispatcher_with_send):
    
    def __init__(self, receiver, sender_sock):
        asyncore.dispatcher_with_send.__init__(self,sender_sock)
        self.receiver = receiver
        
    def handle_read(self):
        try:
            data = self.recv(10240)
            self.receiver.sendall(data)
            print '%4d bytes' % sys.getsizeof(data)
        except Exception,e:
            print e
            self.close()

    def handle_close(self):
        print "closing sender..."
        try:
            self.close()
            self.receiver.close()
            pass
        except Exception, e:
            print e

class ProxyServer(asyncore.dispatcher):

    def __init__(self, host, local_port,remote_ip,remote_port):
        asyncore.dispatcher.__init__(self)
        self.local_port=local_port
        self.remote_ip=remote_ip
        self.remote_port=remote_port
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind((host, local_port))
        
        #self.listen(5)
        #print 'listen...'

    def handle_accept(self):
        pair = self.accept()
        if pair is not None:
            sock, addr = pair
            print '%s connected' % repr(addr)
            handler = Receiver(sock,self.remote_ip,self.remote_port)
            
            return handler
    def run(self):
        print "proxy server running..."
        self.listen(5)
        print 'local port=',self.local_port
        print 'remote ip=',self.remote_ip
        print 'remote port=',self.remote_port
            
if __name__ =='__main__':
    try:
        '''
        import getopt
        opts, args = getopt.getopt(sys.argv[1:], "l:a:p:")
        for op,value in opts:
            if op in ('-l'):
                listenPort=int(value)
            elif op in ('-a'):
                
                remote_ip=value
            elif op in ('-p'):
                
                remote_port=int(value)
            else:
                sys.exit(0)
        '''
        import optparse
        parser = optparse.OptionParser()
        
        parser.add_option(
            '-l','--local-port',
            type='int',dest='local_port',default=80,
            help='Local port')
        parser.add_option(
            '-r','--remote-ip',
            dest='remote_ip',
            help='Remote IP address')
        parser.add_option(
            '-p','--remote-port',
            type='int',dest='remote_port',default=80,
            help='Remote port')
        options, args = parser.parse_args()
    except Exception,e:
        print e
    
    try:
        server = ProxyServer('0.0.0.0', options.local_port,options.remote_ip,options.remote_port)
        #server2 = ProxyServer('0.0.0.0', 6666,options.remote_ip,options.remote_port)
        server.run()
        #server2.run()
        asyncore.loop()
    except Exception, e:
        print e
        

参考资料:

AIM proxy server in python

Asynchronous port forwarding (Python recipe)

经测试,在数据量大的情况下经常出现error 10035.

Asynchronous port forwarding (Python recipe)才是稳定的!

import socket,asyncore

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()
        # print '--- Connect --- '
        sender(receiver(conn),self.remoteip,self.remoteport)

class receiver(asyncore.dispatcher):
    def __init__(self,conn):
        asyncore.dispatcher.__init__(self,conn)
        self.from_remote_buffer=''
        self.to_remote_buffer=''
        self.sender=None

    def handle_connect(self):
        pass

    def handle_read(self):
        read = self.recv(4096)
        # print '%04i -->'%len(read)
        self.from_remote_buffer += read

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

    def handle_write(self):
        sent = self.send(self.to_remote_buffer)
        # print '%04i <--'%sent
        self.to_remote_buffer = self.to_remote_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.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)
        # print '<-- %04i'%len(read)
        self.receiver.to_remote_buffer += read

    def writable(self):
        return (len(self.receiver.from_remote_buffer) > 0)

    def handle_write(self):
        sent = self.send(self.receiver.from_remote_buffer)
        # print '--> %04i'%sent
        self.receiver.from_remote_buffer = self.receiver.from_remote_buffer[sent:]

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

if __name__=='__main__':
    import optparse
    parser = optparse.OptionParser()

    parser.add_option(
        '-l','--local-ip',
        dest='local_ip',default='127.0.0.1',
        help='Local IP address to bind to')
    parser.add_option(
        '-p','--local-port',
        type='int',dest='local_port',default=80,
        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',default=80,
        help='Remote port to bind to')
    options, args = parser.parse_args()

    forwarder(options.local_ip,options.local_port,options.remote_ip,options.remote_port)
    asyncore.loop()
原文地址:https://www.cnblogs.com/nethirte/p/3094488.html