in reply to Port duplicator

From your description, you collect data from the remote port, which seems to indicate that the data is sent in 1 direction only. and that would seem to be simple.

Your redirector script, would seem to be a basic "multi-echo server", simplified by the fact that all clients are listening. The big problem is writing everything inside a while(1) loop which constantly reads the datain socket, checks for new local connections, and echos all the datain to existing local connections.

Without actually writing a working script, this is how I would proceed (step by step). This is untested. I'm not sure if you can use the same port number for your local connections, as for the remote. It would seem you could, but they are different in this example.

#!/usr/bin/perl use warnings; use strict; use IO::Socket; use IO::Select; my @sockets; my $machine_addr = '192.168.0.1'; #your local machine my $remote_addr = '192.168.0.9'; #data supplier #setup datain socket as a client connection my $data_sock = new IO::Socket::INET( PeerAddr=>$remote_addr, PeerPort=>1300, Proto=>'tcp', ); die "Could not connect: $!" unless $data_sock; #setup server for local sockets for local echoing my $main_sock = new IO::Socket::INET( LocalAddr=>$machine_addr, LocalPort=>1200, Proto=>'tcp', Listen=>3, Reuse=>1, ); die "Could not connect: $!" unless $main_sock; print "Starting Server\n"; my $readable_handles = new IO::Select(); $readable_handles->add($main_sock); $readable_handles->add($data_sock); while (1) { ($new_readable) = IO::Select->select($readable_handles, undef, undef +, 0); foreach my $sock (@$new_readable) { #detect and handle new local connections if ($sock == $main_sock) { $new_sock = $sock->accept(); $readable_handles->add($new_sock); } else { #read if it's from data_sock and echo to all except data_sock if ($sock == $data_sock){ my $buf = <$sock>; if ($buf){ print "$buf\n"; my @sockets = $readable_handles->can_write(); @sockets = grep { $_ ne $data_sock } @sockets; #print $sock "You sent $buf\n"; foreach my $sck(@sockets){print $sck "$buf\n";} } else { $readable_handles->remove($sock); close($sock); } } } } } print "Terminating Server\n"; close $main_sock; close $data_sock; getc();

I'm not really a human, but I play one on earth. flash japh

Replies are listed 'Best First'.
Re^2: Port duplicator
by tweetiepooh (Hermit) on Oct 03, 2005 at 10:18 UTC
    Thanks for all the tips, here and in various books and places that monks frequent outside the monestry.

    This is what I have to date, a few little issues to sort out
    #!/usr/local/bin/perl -w # modules required use strict; use IO::Socket; use IO::Tee; use Fcntl; # get port number and server IP my $SERVICE = <DATA>; my $REMOTE = <DATA>; # connection to remote server (data source) my $remote = new IO::Socket::INET( PeerPort => $SERVICE, PeerAddr => $REMOTE, Proto => 'tcp', Type => SOCK_STREAM, ) or die "Can't connect: $!\n"; # local port to accept connections from probes my $local = new IO::Socket::INET( LocalPort => $SERVICE, Proto => 'tcp', Listen => 3, Reuse => 1, ) or die "Can't create server : $!\n"; # make local ports non-blocking fcntl($local,F_SETFL, fcntl($local,F_GETFL,0) | O_NONBLOCK); # build a hash for client connections # use a STDOUT so I can see what's happening on server locally. # can drop for production my %clients = ("StdOut"=>\*STDOUT,); my $buf; # loop forever while (1) { # if a probe connects add details to hash my $client = $local->accept(); $clients{$client} = $client if $client; # this bit remove clients that have disconnected foreach (keys %clients) { delete $clients{$_} if ($_ ne "StdOut" and !$clients{$_}-> +connected()); } # send data to all connected clients my $tee = IO::Tee->new(values %clients); print $tee $buf if (defined $remote and $buf = <$remote>); } __END__ 8099 <server ip goes here>