• 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()
  • 相关阅读:
    关于WebBrowser(浏览器)控件的调用
    SQLite3.0 beta & ADO.NET Data Provider for SQLite 0.18发布了!
    特别推荐:纯VB.NET代码直接生成Excel文件(不需要Excel)
    关于ASP.NET中独立页面设置身份认证等问题
    关于实时网站资源监控
    关于SQLite.org网站给黑...
    .NET中调用COM的一些问题
    关于数据库空字段和DEFAULT值等问题
    关于软件保护的矛与盾
    (转贴) 微软面试100题——要想成为盖茨就来试试!
  • 原文地址:https://www.cnblogs.com/nethirte/p/3094488.html
Copyright © 2020-2023  润新知