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

under TK I need to enable a filehandle to run a sub readdata when the data arrives at Ethernet 192.168.1.199 port 22. I tried the code below but it reports 'bad named parameter FILE'

$port = new Net::Telnet(Timeout => 1000, Port => 22); $port->open(FILE, "192.168.1.199"); $mw->fileevent(\*FILE, 'readable' , \&readdata);

Any ideas??, thanks for your help.

20100908 Janitored by Corion: Added formatting, code tags, as per Writeup Formatting Tips

Replies are listed 'Best First'.
Re: TK filehandle
by zentara (Cardinal) on Sep 06, 2010 at 09:50 UTC
    I'm not familiar with what Net::Telnet does internally, but the following old usenet post may help.... it involves taking the fileevent on the FILEDESCRIPTOR of the socket. The following shows the filedescriptor accessed by sysread, but fileno probably could be used.
    From: [1]Benjamin Goldberg ([2]goldbb2@earthlink.net) Subject: New FAQ idea. Newsgroups: [4]comp.lang.perl.misc Date: 2002-11-16 21:35:19 PST One question that is frequently asked: Why does my IO deadlock, even though I'm using IO::Select or Tk::fi +leevent? You've probably got some code which does something like this: $MW->fileevent( $socket, 'readable', sub { my $line = <$socket> or $MW->fileevent( $socket, 'readable', ''), return; # process $line } ); Or like this: my $select = IO::Select->new($socket); while( () = $select->can_read($timeout) ) { my $line = <$socket> or last; # process $line } The reason for the problem is that <> buffers data, but when IO::Selec +t and Tk::filehandle test for readability, they can only see the underlying *unbuffered* filedescriptor, and the data that gets buffere +d confuses them. The solution is to use the IO operator which works directly on the underlying unbuffered filedescriptor (sysread), and do your buffering yourself, in a seperate variable. Be very careful that sysread is onl +y called *once* for each time that you've been told that a handle is readable -- otherwise, it's quite possible that when the second call i +s made, no data will be there, and you'll get blocked. Change your code to be like one of the following: my $buffer = ""; $MW->fileevent( $socket, 'readable', sub { sysread( $socket, $buffer, 8192, length $buffer ) or $MW->fileevent( $socket, 'readable', '' ), return; while( $buffer =~ s/^(.*\n)// ) { my $line = $1; # process $line } } ); Or like this: my $select = IO::Select->new($socket); my $buffer = ""; while( () = $select->can_read($timeout) ) { sysread( $socket, $buffer, 8192, length $buffer ) or last; while( $buffer =~ s/^(.*\n)// ) { my $line = $1; # process $line } } It's important to be aware that one call to sysread can return less th +an one line, or it could return more than one line. By using a while loo +p in this manner, both cases are dealt with equally well.

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: TK filehandle
by Anonymous Monk on Sep 06, 2010 at 03:23 UTC
    files aren't sockets, you want sockets, example

      The question wasn't about sockets. It was about Net::Telnet objects, which hide most of the socket details and let you use methods like getline and print on the object.

      I think the most important questions here are whether the protocol is really Telnet (especially on port 22, which should normally be ssh instead), whether the code is supposed to implement the server or the client end, whether it's an authenticated session like Telnet normally would be (but isn't always), and where the login handling is done if it is an authenticated session.