in reply to Proxy Server Help

Good ol’ select() is probably your best friend here, and a relatively simple design.   If you think about it, a proxy is always just doing one of three things:   it’s processing a packet that has arrived; or it is processing a connect-request; or, it is snoozing, waiting for one of those other two things to happen.   The amount of CPU-time required to deal with any of these eventualities is virtually non-existent.   No matter how many “active connections” there might be, all of those are simply destinations.   They don’t add to the actual workload, which simply consists of connect-requests and packets.

So, the app really isn’t “multi-threaded” at all.   It’s a simple linear loop, executing in an entirely I/O-constrained fashion that, from the CPU’s point-of-view, isn’t even particularly “fast.”   Like a dutiful mail-clerk, when a letter arrives, drop copies of it into the appropriate outbound slots, and when a connect request arrives, manufacture another slot.   Rinse and repeat.   Work for a few microseconds, then sleep for milliseconds.

Replies are listed 'Best First'.
Re^2: Proxy Server Help
by PhillyR (Acolyte) on Aug 23, 2011 at 19:38 UTC

    Thanks! I reinvestigated the proper use of select and found I was using it wrong. My code now works without forking or pipes or anything other than Select!

    use IO::Socket; use IO::Select; use IO::Handle; $A_lsn = new IO::SOCKET::INET (LocalHost => 'localhost', LocalPort => 1234, Type => SOCK_STREAM, Proto => "tcp", Reuse => 1, Listen => 5) or die "A Server socket couldn't be created: $@\n"; $B_lsn = new IO::SOCKET::INET (LocalHost => 'localhost', LocalPort => 5555, Type => SOCK_STREAM, Proto => "tcp", Reuse => 1, Listen => 5) or die "B Server socket couldn't be created: $@\n"; my $sockets = new IO::Select(); $sockets->add($A); $sockets->add($B); while(@ready = $sockets->can_read) { foreach $sockets (@ready) { if ($sockets == $A_lsn) { #new A client (sends data) $A_sock = $A_lsn->accept() $sockets->add($A_sock); } elsif($sockets == $B_lsn) {#new B client (recv data) $B_sock = $B_lsn->accept(); $sockets->add($B_sock); } elsif($sockets == $A_sock) #A client sent data, forward to all B clients $buf = <$A_sock> my @writers = $sockets->can_write; foreach $writer (@writers) { if ($writer == $A_sock) { #ignore } else { print $writer $buf; } } }