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

Dear Perl Monks,

I am writing a long running perl script that connects to a NNTP server and fetches some articles, decodes the binaries, then fetch some more articles. Everything works fine, but sometimes the NNTP server disconnects me because the decode process takes too long. I want to have a way to test whether the connection is still there or have I timed out.

There needs to be a method that will return true if we are still connnected, and false otherwise. Much like DBI's ping method to test if we are still connected to the database. How would I go about doing this? Of course, there is the easy solution; just re-connect everytime I need to fetch articles. I would like your thoughts.

Btw, I am using Net::NNTP, and I have poked around in the source to see if there's any undocumented methods I can call. But it's all very ugly and I have not found anything that helps.

Replies are listed 'Best First'.
Re: Net::NNTP ping?
by rob_au (Abbot) on Dec 30, 2003 at 08:39 UTC
    Given that the Net::NNTP module inherits from the IO::Socket class, you may find the connected method inherited from this class to be of use. This method returns the peer address if the socket is in a connected state or an undefined value if the socket is not connected.

    For example:

    use Net::NNTP; use Socket; my $nntp = Net::NNTP->new('news-server'); my $hostaddr = $nntp->connected; print inet_ntoa((sockaddr_in($hostaddr))[1]), "\n" if defined $hostadd +r;

     

    perl -le "print+unpack'N',pack'B32','00000000000000000000001010100100'"

      Hello, thanks for the reply. So I wrote a quick one line test. White spaces added so I can read it. Results are as follows:
      perl -MNet::NNTP -MSocket -e ' $n=Net::NNTP->new( localhost, Port=>119, Timeout=>10); sleep 3600; print inet_ntoa((sockaddr_in($n->connected()))[1]) || "not connected"'
      prints out "127.0.0.1" Either the connection is still open (unlikely), or connected() is lying to me.
        At this point, I would be recommending enabling the Debug argument to the Net::NNTP constructor in your script to show NNTP protocol communication between your client script and local news server.

        For example:

        rob@development:/home/rob$ cat nntp.perl use Net::NNTP; use Socket; my $nntp = Net::NNTP->new('news-server', 'Debug' => 1); my $hostaddr = $nntp->connected; print inet_ntoa((sockaddr_in($hostaddr))[1]), "\n" if defined $hostadd +r; rob@development:/home/rob$ perl nntp.perl Net::NNTP>>> Net::NNTP(2.22) Net::NNTP>>> Net::Cmd(2.24) Net::NNTP>>> Exporter(5.562) Net::NNTP>>> IO::Socket::INET(1.25) Net::NNTP>>> IO::Socket(1.26) Net::NNTP>>> IO::Handle(1.21) Net::NNTP=GLOB(0x8262444)<<< 200 Welcome to BigPond Broadband - http:/ +/www.telstra.com/ (Typhoon v2.0.4.336) Net::NNTP=GLOB(0x8262444)>>> MODE READER Net::NNTP=GLOB(0x8262444)<<< 200 Welcome to BigPond Broadband - http:/ +/www.telstra.com/ (Typhoon v2.0.4.336) 61.9.191.5 Net::NNTP=GLOB(0x8262444)>>> QUIT Net::NNTP=GLOB(0x8262444)<<< 205 GoodBye

        Furthermore, I would recommend comparing the return result of the connected method with the socket status as reported by operating system tools such as netstat - The usage of this tool to show the status of established TCP sockets would be netstat -t under Linux and netstat -p tcp under Windows.

         

        perl -le "print+unpack'N',pack'B32','00000000000000000000001010100110'"

Re: Net::NNTP ping?
by robobunny (Friar) on Dec 30, 2003 at 16:15 UTC
    Haven't tested it, but you might be able to get away with checking the response from the 'date' call, which is supposed to give you the time on the news server. It seems like the most minimal call you can make, anyhow.
      Yes, I have tried out the date() method. Although it is part of the rfc, I do not think all servers support it. I've tried it on my private server, which runs leafnode, and it returns undef no matter if I am connected or not. Sample output as follows:
      $ perl -MNet::NNTP -MSocket -e '$n=Net::NNTP->new(localhost,Port=>1199 +,Timeout=>10,Debug=>1);print $n->date()||"undef"' Net::NNTP>>> Net::NNTP(2.22) Net::NNTP>>> Net::Cmd(2.24) Net::NNTP>>> Exporter(5.562) Net::NNTP>>> IO::Socket::INET(1.25) Net::NNTP>>> IO::Socket(1.26) Net::NNTP>>> IO::Handle(1.21) Net::NNTP=GLOB(0x826b0b0)<<< 200 Leafnode NNTP Daemon, version 1.9.31. +rel running at localhost (my fqdn: xxxx.client.attbi.com) Net::NNTP=GLOB(0x826b0b0)>>> MODE READER Net::NNTP=GLOB(0x826b0b0)<<< 200 Leafnode 1.9.31.rel, pleased to meet +you! Net::NNTP=GLOB(0x826b0b0)>>> DATE Net::NNTP=GLOB(0x826b0b0)<<< 500 Unknown command Net::NNTP=GLOB(0x826b0b0)>>> QUIT Net::NNTP=GLOB(0x826b0b0)<<< 205 Always happy to serve! undef ^- output
        That's unforunate. I haven't used Net::NNTP, but with News::NNTPClient, I've used the help() call to check to see if I'm still connected. help also seems to be something that not all servers implement, but if your server has it, and you can run it from Net::NNTP, that might be an option. It probably has a lot more overhead than a simple date call though, especially if the server is actually trying to give you some useful information.