in reply to Help with socket connections

recv might not return undef if the other end of the link vanishes. Try changing:

while (recv ($local_client,$e,1,0)) { print $e; };

into

while (recv ($local_client,$e,1,0)) { print $e; last unless connected( +$local_client) };

____________________
Jeremy
I didn't believe in evil until I dated it.

Replies are listed 'Best First'.
Re: Re: Help with socket connections
by Clownburner (Monk) on Nov 01, 2002 at 20:26 UTC
    Great idea, but it doesn't seem to work. I also tried this:
    while (IO::Socket::connected($local_client) and recv ($local_client,$e +,1,0)) { print $e; last unless IO::Socket::connected($local_client) };
    And it didn't seem to have any effect at all. The TCP sessions themselves are getting stuck in a wibbly-wobbly world. Even after the remote side gets tired of waiting and tries to terminate the connection, I get this:
    fwdport 19309 user 5u IPv4 296408 TCP *:2323 (LISTEN) fwdport 19314 user 6u IPv4 296409 TCP 10.1.10.20:2323->10.1.2.5:6 +0181 (CLOSE_WAIT) fwdport 19314 user 7u IPv4 296412 TCP 10.1.10.20:1044->10.1.1.2:t +elnet (CLOSE_WAIT) fwdport 19315 user 6u IPv4 296409 TCP 10.1.10.20:2323->10.1.2.5:6 +0181 (CLOSE_WAIT) fwdport 19315 user 7u IPv4 296412 TCP 10.1.10.20:1044->10.1.1.2:t +elnet (CLOSE_WAIT)
    Hmmm... Perhaps the while isn't the problem. Maybe there's something weird in the IO::Socket::INET routines?
    "Non sequitur. Your facts are un-coordinated." - Nomad
      IIRC recv doesn't block. Try setting up a test case using something like sysread, which should block, or fail when the socket closes. It will either work, or it will show you that the networking library is truely stuffed. You may be out of luck if the network library is stuffed, since perl tends to call straight through to the system, which means your system libraries are giving you trouble.

      You could probably write your routine using sysread and having it time out in .1 second, which would preserve interactivity.

      ____________________
      Jeremy
      I didn't believe in evil until I dated it.

        Fixed it! With some help from a nice guy on another forum, but this was the solution: The recv call was getting stuck in a loop when the telnet session died unexpectedly - this might be a perl bug. The solution involved IO::Select, which works like a champ:
        # this is the fork's parent, the master's child if ($kidpid) { set_state("$rs_info <-- $lc_info"); my $buf = ""; select($remote_server); $| = 1; my $s=IO::Select->new(); $s->add($local_client); while (my @ready=$s->can_read()) { my $r=recv($local_client,$buf,1,0); warn "local recv - $!" unless(defined($r)); last unless(length($buf)); print $buf; }; print STDOUT "Child Exiting: $lc_info --> $rs_info\n" if $de +bug; log_info(0,$user,$lc_info,$rs_info); # Log disconnect kill('TERM', $kidpid); # kill my twin cause we're done } # this is the fork's child, the master's grandchild else { set_state("$rs_info --> $lc_info"); my $buf = ""; select($local_client); $| = 1; my $s=IO::Select->new(); $s->add($remote_server); while (my @ready=$s->can_read()) { my $r=recv($remote_server,$buf,1,0); warn "remote recv - $!" unless(defined($r)); last unless(length($buf)); print $buf; }; print STDOUT "Grandchild Exiting: $lc_info <-- $rs_info\n" i +f $debug; kill('TERM', getppid()); # kill my twin cause we're done }
        Thanks everyone, for your help on this.
        "Non sequitur. Your facts are un-coordinated." - Nomad