Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm not sure if this is the right venue in which to ask this question, but if anybody could help me out, I'd really appreciate it. I have a perl script written that I run to accept socket connections. It uses IO::Socket and works fine. See the code below:
my $sock = new IO::Socket::INET (LocalPort => 'port',Proto => 'tcp',Li +sten => 1,Reuse=>1); die "Could not create socket: $!\n" unless $sock; my $new_sock = $sock->accept(); while(<$new_sock>) { print $_; } close($sock);


However, the person sending me information via sockets uses netcat. He sends me the info using the line cat /tmp/sock | nc ipaddr port I receive the information fine, but my script does not terminate. It just hangs waiting for more information. I have tried sending socket information using netcat via the cat line above. It seems that netcat doesn't quit. It keeps the socket connection active even after sending the information. My script only stops running when the socket connection dies. So both the sender and receiver are waiting for the connection to die and it never does.

Is there anyway around this either by supplying a command line option to netcat to make it quit after it sends the file or to make my script quit once it receives the information but before the connection dies? Thanks

Replies are listed 'Best First'.
Re: Netcat
by no_slogan (Deacon) on Nov 23, 2002 at 17:36 UTC

    From the netcat documentation:

    This continues indefinitely, until the network side of the connection shuts down. Note that this behavior is different from most other applications which shut everything down and exit after an end-of-file on the standard input.

    It seems likely that netcat is sitting there waiting for replies from your perl script. Can you get your friend to try using the -q switch on netcat? I think that will make it quit after getting an EOF on /tmp/sock (assuming it ever gets one...). Failing that, have you tried using a timeout in your script?

    There doesn't seem to be any way to do a half-close on an IO::Socket::INET, which would seem like the right solution to me. Anyone want to prove me wrong?

    cat /tmp/sock | nc ipaddr port

    Why do people always think they need to do this instead of nc ipaddr port < /tmp/sock?

      There doesn't seem to be any way to do a half-close on an IO::Socket::INET, which would seem like the right solution to me. Anyone want to prove me wrong?
      If no_slogan is right, and I'm guessing he is, try putting this code before your while:
      shutdown($new_sock, 1);
      Let us know if that works.

      Also, if you really want to impress the babes, code your while loop like this:

      print while <$newsock>;
      Updated: 11/25/2002: It works on my system
      cat /tmp/sock | nc ipaddr port
      Why do people always think they need to do this instead of nc ipaddr port < /tmp/sock?

      No idea, its like people not using $_ =)

      -Waswas
Re: Netcat
by hawtin (Prior) on Nov 23, 2002 at 17:02 UTC

    I have never used netcat but an obvious thing to try is to define a specific "I have finished" message. When you script gets that it can close down.