2009-10-19 4 views
0

Я запускаю PHP5 на Windows XP Professional. Я пытаюсь написать php-скрипт telnet, который просто соединяется, отправляет текстовую строку и захватывает буфер ответа и выводит его. Я использую файл класса телнет здесь:php telnet нет ответа от скрипта

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

, который я нашел в другом потоке.

<?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(); 

?> 

Я не получаю никаких ошибок или ответов. Если я отправлю неверную строку, я должен получить ответ «ERR», хотя я даже этого не понимаю. Любые идеи, что я могу делать неправильно? Если я сделаю то же самое из командной строки, я получаю строковый вывод, который мне нужен. Возможно, это связано с тем, что функция записи отправляет

+0

Вы уверены, что ваше соединение преуспевает? –

+0

Есть ли способ проверить, что без прогона провода или эфира? – phill

+0

Я запустил инструкцию connect в классе и, похоже, подключился. – phill

ответ

0

После некоторого чтения в исходном коде и на оригинале (французский) сайта, указанного в заголовке ....

<?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(); 

?> 

Хорошо, объяснение: get_buffer() делает только что прочитал, что в буфере. Чтобы получить что-то в буфере, вы должны выполнить read_to ($ match), который будет считывать в буфер до $ match. После этого get_buffer должен предоставить вам нужную строку.

EDIT: если вы не можете найти строку, которая следует за строку, которую вы заинтересованы в read_to завершится с ошибкой из-за эту часть методы read_to (перевод оригинального французского комментария мой):

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; 
    } 

Значит, когда сокет закрыт без соответствия запрошенной строки, TELNET_ERROR будет возвращен. Тем не менее, строка, которую вы ищете, должна в этот момент находиться в буфере ... Что вы ввели в аргумент read_to? «\ n» вроде того, что я сделал или просто «»?

EDIT2: есть проблема с get_buffer. IMO этот класс не является действительно экономит время ;-)

//------------------------------------------------------------------------ 
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); 
} 

Он выбросит последнюю строку ответа, в вашем случае тот, который содержит ответ. Я предлагаю, чтобы добавить «легкий» вариант get_buffer к классу, как этот

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

}

и сделать необходимую обрезку/поиск в результате самостоятельно.

Вы также можете добавить следующую константу

define ("TELNET_EOF", 3); 

и изменить read_to как этот

... 
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; 
} 
... 

для того, чтобы рассматривать этот частный случай самостоятельно (результат кода TELNET_EOF не должен рассматриваться как ошибка в вашем случае). Итак, ваш код должен выглядеть примерно так:

// 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); 
} 
+0

Awesome..got какой-то хороший прогресс .. Наконец-то получил ответ «Ошибка Telnet на read_to, Не удалось найти запрошенное: '', это не было в данных, возвращаемых с сервера: 'U 808912889'. 'U 808912889' это правильный ответ, который я ищу, интересно, какая запрошенная «ошибка» ... – phill

+0

phill, как работает этот класс, он будет считываться до тех пор, пока не будет найдена какая-либо строка. Подожди, я завариваю еще один ответ или редактирую этот ;-) – fvu

+0

получил это, чтобы работать..важно! grazi mille! – phill

0

Вы не можете вставлять шестнадцатеричные значения. Удаленный процесс просто видит

SRND 1%0d 

и теперь он ждет окончания линии. Попробуйте

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

или

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

двойные кавычки весьма критичны см here

EDIT:

вы можете попробовать добавить некоторые отчеты об ошибках, как сейчас вы не действительно проверьте многое (error_reporting ничего не покажет об ошибках в классе telnet) .... Например:

<?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(); 

?> 

Кроме того, вы уверены, что вам нужно разорвать линию? записи определяется как

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

и делает

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

?

Кроме того, вы проверили хост и порт с помощью telnet-клиента командной строки? Как

telnet 10.10.5.7 2002 

?

+0

Я пробовал это, и я, похоже, получаю тот же результат. я могу столкнуться с проблемой подключения? Я бы предположил, что по крайней мере получаю какой-то вывод или ответ .. – phill

+0

hmm .. попробовал в обоих направлениях .. все еще нет ответа – phill

+0

Когда я telnet в ручном режиме. Я ввожу без кавычек «SNRD 1» и нажимаю enter и он выплескивает правильную строку возврата, поэтому я предполагаю, что мне нужна строка возврата? это помогает? – phill

0

Вы проверили, как работает класс telnet? Возможно, он не предназначен для работы под окнами. Если это простой сокет, с которым вы говорите, возможно, вместо этого используйте обычное сокет-соединение.

http://se2.php.net/sockets

Если открыть сокет, который вы не закроете, вы должны себе запись в NetStat до тех пор, как ваш скрипт работает.

netstat -na|find ":2002"

+0

выглядит как его соединение .. когда я комментирую команду disconnect и запускаю netstat, она отображается как «TCP 10.100.5.2:1703 10.100.5.7:2002 TIME_WAIT» – phill

+0

TIME_WAIT, вероятно, означает, что соединение было закрыто (возможно, удаленным концом), и ваше соединение просто изящно заканчивается. Значение по умолчанию - ждать 240 секунд. Вы должны проверить свой удаленный конец и посмотреть, правильно ли он обрабатывается. – jishi