Zentara, thank you for your help. I feel like I am so close.

Here's the current behavior
1. Turn on server 2
2. Turn on this proxy (code below)
3. Proxy creates 3 listen sockets (server 1, clients for server 1 and clients for server 2)
4. Have client connection for server 2 stream
5. Proxy displays connection, creates a socket to server 2, server 2 starts sending data to this client. After about 2 seconds of transfer the stream hangs.
6. I try a secondary client for server 2. No connection
7. I press any key on the proxy command prompt and hit enter
8. Server 2 resumes sending data, second client connects and starts to get data
9. Behavior is as would be expected (multiple client connecting, STDIN is being read, no hanging)

How do I get rid needing step 7? Should each of my stream subroutines use the sysread as well? I would like the stream coming from either server to be unmodified

Here is my current code:

#!/usr/bin/perl -w # ----------------------------- use warnings; use strict; use IO::Socket; use IO::Select; use Term::ReadKey; use threads; use threads::shared; $|++; # ----------------------------- # ----------------------------- our @stream1_clients : shared; our @stream2_clients : shared; my $stream1_prt = 5555; my $stream2_prt = 5556; my $client1_prt = 1100; my $client2_prt = 1101; my $ip = '192.168.1.12'; # ----------------------------- # Create Stream 1 listen ------ my $stream1_lsn = new IO::Socket::INET (LocalAddr => $ip, LocalPort => $stream1_prt, Type => SOCK_STREAM, Proto => "tcp", Reuse => 1, Listen => 5) or die "Stream 1 listen socket couldn't be created: $@\n"; # ----------------------------- # Create Client 1 listen ------ my $client1_lsn = new IO::Socket::INET (LocalAddr => $ip, LocalPort => $client1_prt, Type => SOCK_STREAM, Proto => "tcp", Reuse => 1, Blocking => 0, #part of issue? Listen => 5) or die "Client 1 listen socket couldn't be create: $@\n"; # ----------------------------- # Create Client 2 listen ------ my $client2_lsn = new IO::Socket::INET (LocalAddr => $ip, LocalPort => $client2_prt, Type => SOCK_STREAM, Proto => "tcp", Reuse => 1, Blocking => 0, #part of issue? Listen => 5) or die "Client 2 listen socket couldn't be create: $@\n"; # ----------------------------- # Add listen sockets to select my $sockets = new IO::Select(); $sockets->add($stream1_lsn); $sockets->add($client1_lsn); $sockets->add($client2_lsn); # ----------------------------- # Create separate thread for nonblocking read of STDIN my $thr_in = threads->new(\&read_in)->detach(); #Go into infinite loop, handling connections while(my @ready = $sockets->can_read) { #got data foreach my $socket (@ready) { # find which socket sent data #New Stream1--------------------- if ($socket == $stream1_lsn) { my $stream1_sock = $stream1_lsn->accept(); #accept stream 1 $stream1_hst = $stream1_sock->peerhost; print "New stream1 from IP [$stream1_hst]\n"; my $thr_stream1 = threads->new(\&stream1, $stream1_sock)->detach +(); } # ----------------------------- #New client1 ------------------ elsif ($socket == $client1_lsn) { my $client1_sock = $client1_lsn->accept(); #accept client 1 $sockets->add($client1_sock); #add socket to select my $fileno = fileno $client1_sock; push (@stream1_clients, $fileno); $client1_hst = $client1_sock->peerhost; print "New client for stream 1 @ IP [$client1_hst]\n"; } # ----------------------------- #New client2 ------------------ elsif ($socket == $client2_lsn) { my $client2_sock = $client2_lsn->accept(); #accept client 2 $sockets->add($client2_sock); #add socket to select my $fileno2 = fileno $client2_sock; push(@stream2_clients, $fileno2); $client2_hst = $client2_sock->peerhost; print "New client for stream 2 @ IP [$client2_hst]\n"; #Connection to second server running locally my $stream2_sock = new IO::Socket::INET( PeerAddr => 'localhost', PeerPort => $stream2_prt, Type => SOCK_STREAM, Proto => "tcp") or die "Stream2 socket couldn't be created: $@\n"; my $thr_stream2 = threads->new(\&stream2, $stream2_sock)->detach +(); } # ----------------------------- } } # Routine called by thread to send stream 1 sub stream1 { my ($lclient1) = @_; my $buf1; if ($lclient1->connected) { while(defined($buf1=<$lclient1>) { foreach $fn1 (@stream1_clients) { open my $fh1, ">&=fn1" or warn $! and die; binmode($fh1, ":raw"); print $fh1 $buf1; } } } close ($lclient1); } # ----------------------------- # Routine called by thread to send stream 2 sub stream2 { my ($lclient2) = @_; my $buf2; if ($lclient2->connected) { while(defined($buf2=<$lclient2>) { foreach $fn2 (@stream2_clients) { open my $fh2, ">&=fn2" or warn $! and die; binmode($fh2, ":raw"); print $fh2 $buf2; } } } close ($lclient2); } # ----------------------------- # Read STDIN in nonblocking fashion?? sub read_in { while (1) { my $char; if(defined($char = ReadKey(0)) ) { if ($char eq 'q') { exit; } } } } __END__

In reply to Re^8: Problem handling 2 simultaneous socket streams by PhillyR
in thread Problem handling 2 simultaneous socket streams by PhillyR

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.