tags:

views:

279

answers:

3

I'm running PHP5 on Windows XP Professional. I'm trying to write a telnet php script which simply connects, sends a text string and grabs the response buffer and outputs it. I'm using the telnet class file from here:

http://cvs.adfinis.ch/cvs.php/phpStreamcast/telnet.class.php

which i found in another thread.

<?php 
error_reporting(255);
ini_set('display_errors', true);

echo "1<br>";
require_once("telnet_class.php");

$telnet = new Telnet(); 

$telnet->set_host("10.10.5.7"); 
$telnet->set_port("2002");
$telnet->connect();
//$telnet->wait_prompt();
$telnet->write('SNRD   1%0d');
echo "3<br>";
$result = $telnet->get_buffer();
        echo $result;
        print_r($result);
//        flush_now();
echo "4<br>";

$telnet->disconnect();

?>

I'm not receiving any kind of errors or response. If I send an invalid string, I should get an 'ERR' response in the least however I don't even get that. Any ideas what i could be doing wrong? If I do the same thing from the command prompt, I receive the string output I need. Could this is because the write function is sending

A: 

You can't insert hex values like that. The remote process just sees

SRND   1%0d

and now it's waiting for the line to be terminated. Try this

$telnet->write('SNRD   1' . "\r");

or

$telnet->write("SNRD   1\xd");

The double quotes are quite critical, see here

EDIT:

you might try adding some error reporting as right now you don't really check much (error_reporting won't show anything on the errors in the telnet class).... For example:

<?php 
error_reporting(255);
ini_set('display_errors', true);

echo "1<br>";
require_once("telnet_class.php");

$telnet = new Telnet(); 

$telnet->set_host("10.10.5.7"); 
$telnet->set_port("2002");
if ($telnet->connect() != TELNET_OK) {
     printf("Telnet error on connect, %s\n",$telnet->get_last_error());
}
//$telnet->wait_prompt();
if ($telnet->write('SNRD   1' . "\xd") != TELNET_OK) {
     printf("Telnet error on write, %s\n",$telnet->get_last_error());
}

echo "3<br>";
$result = $telnet->get_buffer();
        echo $result;
        print_r($result);
//        flush_now();
echo "4<br>";

$telnet->disconnect();

?>

also, are you sure you need \r\n line termination? write is defined as

function write($buffer, $valeurLoggee = "", $ajouterfinLigne = true){

and does

    if ($ajouterfinLigne){
        $buffer .= "\n";
    }

?

Also, did you test the host and port with the command line telnet client? Like

telnet 10.10.5.7 2002

?

fvu
I tried that and I seem to get the same result. could I be experiencing a connection problem? I would assume I would at least get some kind of output or response..
phill
hmm.. tried it both ways.. still no response
phill
When I telnet in manually.. I type in without quotes "SNRD 1" and hit enter and it spits out the correct return string so i'm guessing i need a return string? does this help?
phill
Found it - I'll make a new reply ASAP
fvu
A: 

Have you checked how the telnet class works? Maybe it wasn't designed to run under windows. If it's a simple socket that you're speaking to, maybe consider using a regular socket-connection instead.

http://se2.php.net/sockets

If you open up a socket which you don't close, you should se an entry in netstat as long as your script is running.

netstat -na|find ":2002"

jishi
looks like its connecting.. when i comment out the disconnect command and run the netstat, it shows up as "TCP 10.100.5.2:1703 10.100.5.7:2002 TIME_WAIT"
phill
TIME_WAIT probably means that the connection has been closed (probably by remote end) and your connection is just gracefully finishing. The default setting is to wait for 240 sec. You should check your remote end and see if it is handled correctly.
jishi
A: 

After some reading in the source code and on the original (french) site referred to in the header....

<?php 
error_reporting(255);
ini_set('display_errors', true);

echo "1<br>";
require_once("telnet_class.php");

$telnet = new Telnet(); 

$telnet->set_host("10.10.5.7"); 
$telnet->set_port("2002");
if ($telnet->connect() != TELNET_OK) {
     printf("Telnet error on connect, %s\n",$telnet->get_last_error());
}
//$telnet->wait_prompt();
if ($telnet->write('SNRD   1' . "\xd") != TELNET_OK) {
     printf("Telnet error on write, %s\n",$telnet->get_last_error());
}

// read to \n or whatever terminates the string you need to read
if ($telnet->read_to("\n") != TELNET_OK) {  
     printf("Telnet error on read_to, %s\n",$telnet->get_last_error());
}
echo "3<br>";


$result = $telnet->get_buffer();
        echo $result;
        print_r($result);
//        flush_now();
echo "4<br>";

$telnet->disconnect();

?>

Okay, explanation: get_buffer() does just that, read what's in the buffer. To get something in the buffer you have to execute read_to($match) who will read into buffer up to $match. After that, get_buffer should give you the desired string.

EDIT: if you cannot find some string that follows the string you are interested in read_to will end in an error due to this part of the read_to method (translation of original french comment is mine):

    if ($c === false){
     // plus de caracteres a lire sur la socket
     // --> no more characters to read on the socket
        if ($this->contientErreur($buf)){
            return TELNET_ERROR;
        }

        $this->error = " Couldn't find the requested : '" . $chaine . "', it was not in the data returned from server : '" . $buf . "'" ;
        $this->logger($this->error);
        return TELNET_ERROR;
    }

Meaning that when the socket is closed without a match of the requested string, TELNET_ERROR will be returned. However, the string you're looking for should at that point be in the buffer.... What did you put in read_to's argument? "\n" like what I did or just "" ?

EDIT2 : there's also a problem with get_buffer. IMO this class is not really a timesaver ;-)

//------------------------------------------------------------------------
function get_buffer(){
    $buf = $this->buffer;

    // cut last line (is always prompt)
    $buf = explode("\n", $buf);
    unset($buf[count($buf)-1]);
    $buf = join("\n",$buf);
    return trim($buf);
}

It will throw away the last line of the response, in your case the one that contains the answer. I suggest to add a "light" version of get_buffer to the class, like this

//------------------------------------------------------------------------
function get_raw_buffer(){
    return $this->buffer;

}

and do the necessary trimming/searching in the result yourself.

You might also want to add the following constant

define ("TELNET_EOF", 3);

and change read_to like this

...
if ($c === false){
    // plus de caracteres a lire sur la socket
    if ($this->contientErreur($buf)){
        return TELNET_EOF;
    }

    $this->error = " Couldn't find the requested : '" . $chaine . "', it was not in the data returned from server : '" . $buf . "'" ;
    $this->logger($this->error);
    return TELNET_EOF;
} 
...

in order to treat that special case yourself (a result code TELNET_EOF doesn't have to be treated as an error in your case). So finally your code should look more or less like this:

// read to \n or whatever terminates the string you need to read 
if ($telnet->read_to("\n") == TELNET_ERROR) {  
    printf("Telnet error on read_to, %s\n",$telnet->get_last_error()); } echo "3<br>";
} else {
    $result = $telnet->get_raw_buffer();
    echo $result;
    print_r($result);
}
fvu
Awesome..got some good progress.. Finally got a response "Telnet error on read_to, Couldn't find the requested : ' ', it was not in the data returned from server : 'U 808912889 '. The 'U 808912889' is the correct response I'm looking for, wonder what the requested ' ' error is...
phill
phill, the way this class works it will read until some string is found. Wait, I'll brew yet another reply or edit this one ;-)
fvu
got it to work..awesome! grazi mille!
phill
I was almost getting desperate ;-) Glad to help!
fvu