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

I'm trying to write a cool Games::Go::NNGS module. Well, I'm not sure what it'll be called, but that seems reasonable. I usually wait ot decide on a name until I have enough module to bother.

Heh. Anyway. I'll need to telnet in, and read/write from the socket. I'd prefer to have the module call function callbacks for events it detects.

It seems like a reasonably good place to use threads, but not everyone has perl compiled with threads. So I was looking at IPC::SysV. I remember reading that's flaky?

Is there a better solution to my telnet and let control pass back to the caller problem?

I found this mud client which sounded helpful, but my my $o = new Games::Go::NNGS would never return...

And so, I'm asking about IPC::SysV. Well, for an alternative. Am I missing a cool Net::Telnet::Callbacks or something? Should I use sockets or something? Should I just force people to recompile perl in order to use a threaded module?

I don't like that last one because of my Sendmail::Milter troubles... Recompiling perl on a P60 sucks.

update (broquaint): title change (was NNGS)

Replies are listed 'Best First'.
Re: non-blocking TCP/IP client object using callbacks
by castaway (Parson) on Jul 22, 2003 at 12:08 UTC
    I don't quite see what your overall question is, but to answer some of the bits:

    No theres no Net::Telnet::Callbacks that I know of, and I really wouldn't recommend Net::Telnet for anything than talking to real telnet servers (maybe I'm biased tho, I don't like it..) Although, telnet has options, and Net::Telnet does event stuff based on those, I think.

    Sockets would be a good idea, you could write that easy to do callbacks.

    Threads are a bit of a pain together with Sockets etc. (In my experience), I've a fairly complicated telnet/mud client using 5.005 threads, which is complicated enough, but still not managed to convert to ithreads, which are more difficult to use (and dont allow sharing of objects) ..

    Theres some IO::Socket stuff on castaway's scratchpad if you need a starter on that (the im2 script).

    (No experience with/knowledge of IPC::SysV, and no idea why you shouldn't use Sockets :)

    I can give you a link to my (rather bulky and also flaky), telnet client with modules, events and all sorts of junk, if you'd like :)

    C.

      No, I'm not really afraid of socket programming either. I failed to explain myself is all. I had actually planned on having to clarify. I'm just not very good with the english... Meh.

      The question is really: What's the best way to implement a client object that can read and write to a socket, but that passes control back to the caller, and that passes received lines back to the caller via a set of function callbacks.

      So far, I rather think I'll end up doing this with IPC and a fork() because it'll be the most portable. Well, I'm not 100% on that. Does IPC and fork even work on windows? I wouldn't know. But I do know that threads don't work everywhere.

        Perhaps the caller could periodically pass the controll back to the socket listener? Thus you would not need the parallelism whis is allways a bit tricky.
Re: non-blocking TCP/IP client object using callbacks
by zby (Vicar) on Jul 22, 2003 at 12:06 UTC
    As far as I understand your question you want to write a client server application where the client is actually the telnet program (very thin client) so the server is a console TCP daemon. Since the server is supposed to serve more then one client you need to have a mechanism for parallel request processing. Or perhaps you don't? Are you sure you need that? Can't the requests just wait in a queue? If you really need to process the requests in parallel you can achieve this in a few ways:
    • by inetd (forked new daemon process for each connection)
    • by implementing the parallelism in your program:
      • by forking in your program
      • by using threads
      • other mechanisms like cooperative parallelism in POE
    I hope this will help you to choose the architecture.

      See, this is why I shoulda studied more in english. I fail to make myself clear every time...

      I wish to use Net::Telnet or IO::Sockets actually. And I'm connecting to a remote server, so inetd doesn't really apply. But I don't wish for control to remain stuck in the module...

      When my module receives messages, it should pass them to the actual application via callbacks.

      POE is really neat looking! I hadn't seen that before, but it's probably a bad fit for a telnet client object.

        Actually, POE should work just great as a telnet client. Here's an example of a simple "port scanner" that shows how easy it is to make a TCP client with POE::Component::Client::TCP. There are a lot more useful examples at the POE Cookbook. Also, since POE is event based it will do exactly what you were wanting as far as passing the messages to whatever subroutine you want via callback.

        It may take a little while to get used to writing programs with POE, but I highly recommend it! It is much simpler than threads and you don't have to worry about IPC like you would with forking because it's all the same process.