simple socket redirector app question

Steve Holden sholden at holdenweb.com
Wed Jun 19 11:02:42 EDT 2002


"Michael Gilfix" <mgilfix at eecs.tufts.edu> top-posted the code ...
>   I think SocketServer is a good choice for this. SocketServer is
> aimed at providing a easy to drop-in infrastructure for apps that
> don't require any complicated server setup. SocketServer would make
> this quick and compact. Essentially you just want to read from one
> socket and write to the other. Via inhertiance you could construct
> a bridge class that contains two socket servers and talks between
> them...
>
>                    -- Mike
>
> On Mon, Jun 17 @ 13:27, Bruce Edge wrote:
> > I have an app which talks via sockets to local host clients only.
> > I'd like to get at it remotely.
> >
> > Basically it would accept remote connections from a remote client,
> > relay them the the local app, and forward the replies back to the
> > remote client.
> >
> > What's the simplest way to write this type of a socket redirector?
> >
> > Use SocketServer, or is that overkill?
> >

There's also a suitable proxy in the Medusa distribution, available from Sam
Rushing's nightmare.com site. Here's a slightly-modified copy I used in
"Python Web Programming". It's perhaps a bit more general than you really
need, but I founf it an excellent demonstration of asyncore's operation.

regards
 Steve
----------------------------- Code Follows ----------------------------
import asynchat
import asyncore
import socket
import string

class proxy_server(asyncore.dispatcher):

    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.there =(host, port)
        here =('', port + 8000)
        self.bind(here)
        self.listen(5)

    def handle_accept(self):
        proxy_receiver(self, self.accept())

class proxy_sender(asynchat.async_chat):

    def __init__(self, receiver, address):
        asynchat.async_chat.__init__(self)
        self.receiver = receiver
        self.set_terminator(None)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.buffer = ''
        self.set_terminator('\n')
        self.connect(address)

    def handle_connect(self):
        print 'Connected'

    def collect_incoming_data(self, data):
        self.buffer = self.buffer + data

    def found_terminator(self):
        data = self.buffer
        self.buffer = ''
        print '==>(%d) %s' %(self.id, repr(data))
        self.receiver.push(data + '\n')

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

class proxy_receiver(asynchat.async_chat):

    channel_counter = 0

    def __init__(self, server,(conn, addr)):
        asynchat.async_chat.__init__(self, conn)
        self.set_terminator('\n')
        self.server = server
        self.id = proxy_receiver.channel_counter
        proxy_receiver.channel_counter = proxy_receiver.channel_counter + 1
        self.sender = proxy_sender(self, server.there)
        self.sender.id = self.id
        self.buffer = ''

    def collect_incoming_data(self, data):
        self.buffer = self.buffer + data

    def found_terminator(self):
        data = self.buffer
        self.buffer = ''
        print '<==(%d) %s' %(self.id, repr(data))
        self.sender.push(data + '\n')

    def handle_close(self):
        print 'Closing'
        self.sender.close()
        self.close()

if __name__ == '__main__':
    import sys
    import string
    if len(sys.argv) < 3:
        print 'Usage: %s <server-host> <server-port>' % sys.argv[0]
    else:
        ps = proxy_server(sys.argv[1], string.atoi(sys.argv[2]))
        asyncore.loop()

-----------------------------------------------------------------------
Steve Holden                                 http://www.holdenweb.com/
Python Web Programming                http://pydish.holdenweb.com/pwp/
-----------------------------------------------------------------------








More information about the Python-list mailing list