http://www.perlmonks.org?node_id=208006

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

I've just rolled my own server ( in C because it ties into C APIs ). I'm writing a client in Perl to sit on another machine and interogate it.

The problem is, that I can telnet to the server and the server works, returning the grid reference for a location or postcode.

Using the Perl, client the data is sent and the server replies (I can see that from the server log) but the data data doesn't appear back on the client, untill I close the server down, presumably closing the pipe.

I know I've done something fundamentally stoopid, what is it?

Here is the code:

#!/usr/local/bin/perl use strict; use warnings; use IO::Socket; use Data::Dumper; $|=1; my $remote_host = '1XX.1XX.XX.XX'; my $remote_port = 1139; my $socket = IO::Socket::INET->new ( PeerAddr => $remote_host, PeerPort => $remote_port, Proto => "tcp", Type => SOCK_STREAM ) or die "Couldn't connect to $remote_host:$remote_port +: $@\n"; $socket->autoflush(1); while (<>){ print $socket $_; my @answer = <$socket>; print Dumper \@answer; } close( $socket );

--

Brother Frankus.

¤

Replies are listed 'Best First'.
Re: Socket gripes
by sch (Pilgrim) on Oct 25, 2002 at 14:35 UTC

    I suspect that the read you're doing is waiting for a \n or \r before returning and that your server isn't supplying one - I had a similar problem on some socket code I was working with and the problem was solved by using sysread.

    But today you took me walking, Through a land that we have lost,
    While our children sit at websites, With no access to the cost

      Cheers for the prompt response.

      The problems I percieve with this are that the return data already stretches over several lines and contains a return character at the end of each line..

      If you mean it needs a return character after the last line..
      I am loathe to add an extra return character to provide Perl with a quick fix, when it may inpinge on other clients in other languages.

      --

      Brother Frankus.

        As a test, and to see if the return is the problem, could I suggest using sysread to read back 1 character at a time to see if you get stuff returned immediately or whether it still sits waiting.

        But today you took me walking, Through a land that we have lost,
        While our children sit at websites, With no access to the cost

Re: Socket gripes
by Thelonius (Priest) on Oct 25, 2002 at 15:38 UTC
    The problem is that with this line:
    my @answer = <$socket>;
    you are saying to Perl to read in the whole "file", so of course it won't return until the socket is closed. Your protocol needs to have some way to tell when your server has finished talking. There are lots of ways to do this, you just have to make sure that your data won't accidentally trigger that condition.

    Common ways are to:

    1. prefix the response with the length of the data
    2. or, send a blank line when you're done
    3. or, send a dot on a line by itself
    4. or, prefix each line with some character that indicates whether or not it's the last line
      Why would that read the whole file for $socket, when he's not changing the global $/ (input record separator)?
        Because he is using < > (readline) in list context.
      I'm sure it's not the friday afternoon beers speaking ( that the managers dispense like Captain Ahab..
      "Drink and pass!" he cried, handing the heavy charged flagon to the
      nearest seaman.  "The crew alone now drink.  Round with it, round!
      Short draughts--long swallows, men; 'tis hot as Satan's hoof."  
      
      )

      I digress... I am sure it is not the ale speaking when I say many thanks for this precise and calming answer ;o)

      --

      Brother Frankus.