我在Windows XP Professional上运行PHP5。我正在尝试编写一个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)
您不能像这样插入十六进制值。远程进程只看到了
SRND 1%0d
现在它正在等待终止线路。试试这个
$telnet->write('SNRD 1' . "\r");
或
$telnet->write("SNRD 1\xd");
双引号非常重要,请参阅here
编辑:
您可能会尝试添加一些错误报告,因为您现在没有真正检查太多(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();
?>
另外,你确定你需要\ r \ n线路终止吗? write定义为
function write($buffer, $valeurLoggee = "", $ajouterfinLigne = true){
并且确实
if ($ajouterfinLigne){
$buffer .= "\n";
}
另外,您是否使用命令行telnet客户端测试主机和端口?像
telnet 10.10.5.7 2002
答案 1 :(得分:0)
你检查过telnet类是如何工作的吗?也许它不是设计在Windows下运行。如果它是一个与您交谈的简单套接字,可以考虑使用常规套接字连接。
如果打开一个未关闭的套接字,只要脚本正在运行,就应该在netstat中输入一个条目。
netstat -na|find ":2002"
答案 2 :(得分: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应该为您提供所需的字符串。
编辑: 如果你找不到一些你感兴趣的字符串后面的字符串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也有问题。国际海事组织这个班级并不是真正的节省时间; - )
//------------------------------------------------------------------------
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);
}