in reply to IO::Socket tutorial

First off, that seems to presume that you have a unix handy to check on the system call.

There are lots of webpages out there to look up man pages, such as

No manual entry for send in section 2

On Debian-based systems like Ubuntu, there's a package manpages-dev that contains these man pages.

timeout mechanism

In my experience this can be accomplished with e.g. select (the multi-arg version), or the slightly higher-level IO::Select.

However, send and select are relatively low-level. Over time I've become more and more convinced that really the best way to do any communication with a delay is an asynchronous event-based system, of which select(2) is only the simplest. It takes a little getting used to, but it solves so many of the problems that synchronous code can suffer from that IMHO it's worth it. For example, I've used POE successfully (it has a bit of a learning curve but there's a cookbook), and recently I've been doing more with Mojolicious, and you can use its Mojo::IOLoop::Client and Mojo::IOLoop::Stream to implement a TCP client (Update: I posted an example here). If you were to show some example client code I might have the time to show what they would look like in Mojo.

Replies are listed 'Best First'.
Re^2: IO::Socket tutorial
by BernieC (Monk) on Feb 19, 2020 at 12:25 UTC
    Thanks -- I'll look at POE. As for example client code, it is just unbelievably {and unfixably} dumb:
    sub command { my $cmd = "$_[0]\r\n" ; print $server $cmd ; my $resp = <$server> ; return undef if $resp !~ /^[123]/ ; return $resp ; }
    I don't even remember what got me thinking that IO::Socket's can be used as file descriptors {I just looked and can't find it in the man pages..sigh} I guess what I can do is do a 'send' with the $cmd my sub is given and then I need to replace the <$server> with something that'll timeout and then I can close/reopen the socket and try again. POE seems fancier than I need for this {although I see that it can handle the event loop of Tk, something I had trouble getting to work correctly}
      I don't even remember what got me thinking that IO::Socket's can be used as file descriptors

      Technically they can be used like handles (not descriptors), they're subclasses of IO::Handle. But as you discovered, doing a readline on them is blocking; from my experience I very much prefer non-blocking operations, and those are IMHO best abstracted via an event-based interface.

      In terms of example code, I should have been more specific: a Short, Self-Contained, Correct Example.

        I seem to have replied but forgot to post it... duh. Anyhow, I'm thinking of sticking with IO::Select and it looks very easy. I create a new Select object initialized to my TCP connection, then I can do a can_read with a timeout, and if it doesn't time out I can use ->getlines to suck up what was sent. If that's all that I was expecting {the returned stuff is terminated by a line with just a ".", as with RCS and unix-mail} I'm done, otherwise I go back and can_read again. Either I get all I needed or a can_read returns a timeout. Seems pretty easy... I can handle the recovery code when it times out. THANKS!!