我使用telnet PHP类与Windows机器通信。类停止以特殊字符读取缓冲区的问题(可能将其视为提示),因此它不会返回完整的结果。类代码的哪一部分对此
有响应 <?php
/**
* Telnet class ver 0.1.4
* ----------------------
*
* Modified version by Dmitry Shin <dmitry.s@hsdn.org>, 2013-2015
*
* Used to execute remote commands via telnet connection
* Usess sockets functions and fgetc() to process result
*
* All methods throw Exceptions on error
*
* Written by Dalibor Andzakovic <dali@swerve.co.nz>
* Based on the code originally written by Marc Ennaji and extended by
* Matthias Blaser <mb@adfinis.ch>
*/
class Telnet
{
private $host;
private $port;
private $timeout;
private $socket = NULL;
private $buffer = NULL;
private $prompt;
private $errno;
private $errstr;
private $header1;
private $header2;
public $NULL;
public $CR;
public $DC1;
public $WILL;
public $WONT;
public $DO;
public $DONT;
public $IAC;
public $LINEMODE;
const TELNET_ERROR = FALSE;
const TELNET_OK = TRUE;
/**
* Constructor. Initialises host, port and timeout parameters
* defaults to localhost port 23 (standard telnet port)
*
* @access public
* @param string $host Host name or IP addres
* @param int $port TCP port number
* @param int $timeout Connection timeout in seconds
* @return void
*/
public function __construct($host = '127.0.0.1', $port = 23, $timeout = 10)
{
$this->setPrompt();
$this->host = $host;
$this->port = $port;
$this->timeout = $timeout;
$this->header1 =
chr(0xFF).chr(0xFB).chr(0x1F). // 0xFF 0xFB 0x1F - WILL command - NEGOTIATE-WINDOW-SIZE
chr(0xFF).chr(0xFB).chr(0x20). // 0xFF 0xFB 0x20 - WILL command - TERMINAL-SPEED
chr(0xFF).chr(0xFB).chr(0x18). // 0xFF 0xFB 0x18 - WILL command - TERMINAL-TYPE
chr(0xFF).chr(0xFB).chr(0x27). // 0xFF 0xFB 0x27 - WILL command - NEW-ENVIRON
chr(0xFF).chr(0xFD).chr(0x01). // 0xFF 0xFD 0x01 - DO command - ECHO
chr(0xFF).chr(0xFB).chr(0x03). // 0xFF 0xFB 0x03 - WILL command - SUPPRESS-GO-AHEAD
chr(0xFF).chr(0xFD).chr(0x03). // 0xFF 0xFD 0x03 - DO command - SUPPRESS-GO-AHEAD
chr(0xFF).chr(0xFC).chr(0x23). // 0xFF 0xFC 0x23 - WON'T command - X-DISPLAY-LOCATION
chr(0xFF).chr(0xFC).chr(0x24). // 0xFF 0xFC 0x24 - WON'T command - ENVIRONMENT
chr(0xFF).chr(0xFA). // 0xFF 0xFA ... - SB command
chr(0x1F).chr(0x00).chr(0x50).chr(0x00).chr(0x18). // NEGOTIATE-WINDOW-SIZE
// <Width1>=0 <Width0>=80 <Height1>=0 <Height0>=24
chr(0xFF).chr(0xF0). // 0xFF 0xF0 - SE command
chr(0xFF).chr(0xFA). // 0xFF 0xFA ... - SB command
chr(0x20).chr(0x00).chr(0x33).chr(0x38).chr(0x34).
chr(0x30).chr(0x30).chr(0x2C).chr(0x33).chr(0x38).
chr(0x34).chr(0x30).chr(0x30). // TERMINAL-SPEED - 38400,38400
chr(0xFF).chr(0xF0). // 0xFF 0xF0 - SE command
chr(0xFF).chr(0xFA). // 0xFF 0xFA ... - SB command
chr(0x27).chr(0x00). // NEW-ENVIRON <IS> <empty>
chr(0xFF).chr(0xF0). // 0xFF 0xF0 - SE command
chr(0xFF).chr(0xFA). // 0xFF 0xFA ... - SB command
chr(0x18).chr(0x00).chr(0x58).chr(0x54).chr(0x45).
chr(0x52).chr(0x4D). // TERMINAL-TYPE: <IS> XTERM
chr(0xFF).chr(0xF0); // 0xFF 0xF0 - SE command
$this->header2 =
chr(0xFF).chr(0xFC).chr(0x01). // 0xFF 0xFC 0x01 - WON'T command - ECHO
chr(0xFF).chr(0xFC).chr(0x22). // 0xFF 0xFC 0x22 - WON'T command - LINEMODE
chr(0xFF).chr(0xFE).chr(0x05). // 0xFF 0xFE 0x05 - DON'T command - STATUS
chr(0xFF).chr(0xFC).chr(0x21); // 0xFF 0xFC 0x21 - WON'T command - TOGGLE-FLOW-CONTROL
$this->NULL = chr(0);
$this->CR = chr(13);
$this->DC1 = chr(17);
$this->WILL = chr(251);
$this->WONT = chr(252);
$this->DO = chr(253);
$this->DONT = chr(254);
$this->IAC = chr(255);
$this->LINEMODE = chr(34);
$this->connect();
}
/**
* Destructor. Cleans up socket connection and command buffer
*
* @access public
* @return void
*/
public function __destruct()
{
$this->disconnect();
$this->buffer = NULL;
}
/**
* Attempts connection to remote host. Returns TRUE if sucessful.
*
* @access public
* @return bool
*/
public function connect()
{
if (!preg_match('/([0-9]{1,3}\\.){3,3}[0-9]{1,3}/', $this->host))
{
$ip = gethostbyname($this->host);
if($this->host == $ip)
{
throw new Exception("Cannot resolve ".$this->host.".");
}
else
{
$this->host = $ip;
}
}
$this->socket = @fsockopen($this->host, $this->port, $this->errno, $this->errstr, $this->timeout);
$this->write($this->header1, FALSE);
usleep(100800);
$this->write($this->header2, FALSE);
usleep(100800);
if (!$this->socket)
{
throw new Exception("Cannot connect to ".$this->host." on port ".$this->port.".");
}
return self::TELNET_OK;
}
/**
* Closes IP socket
*
* @access public
* @return bool
*/
public function disconnect()
{
if ($this->socket)
{
$this->write('quit');
if (!fclose($this->socket))
{
throw new Exception("Error while closing telnet socket.");
}
$this->socket = NULL;
}
return self::TELNET_OK;
}
/**
* Executes command and returns a string with result.
* This method is a wrapper for lower level private methods
*
* @access public
* @param string $command Command to execute
* @return string Command result
*/
public function exec($command)
{
$this->write($command);
$this->waitPrompt();
return $this->getBuffer();
}
/**
* Attempts login to remote host.
* This method is a wrapper for lower level private methods and should be
* modified to reflect telnet implementation details like login/password
* and line prompts. Defaults to standard unix non-root prompts
*
* @access public
* @param string $username Username
* @param string $password Password
* @return bool
*/
public function login($username = FALSE, $password = FALSE)
{
try
{
if ($username)
{
$this->setPrompt('/(ogin|name|word):.*$/');
$this->waitPrompt();
$this->write($username);
}
if ($password)
{
$this->setPrompt('/word:.*$/');
$this->waitPrompt();
$this->write($password);
}
$this->setPrompt();
$this->waitPrompt();
}
catch (Exception $e)
{
throw new Exception("Login failed.");
}
return self::TELNET_OK;
}
/**
* Sets the string of characters to respond to.
* This should be set to the last character of the command line prompt
*
* @access public
* @param string $s String to respond to
* @return bool
*/
public function setPrompt($s = '/[^\s]{2,}[\$%>] {0,1}$/')
{
$this->prompt = $s;
return self::TELNET_OK;
}
/**
* Gets character from the socket
*
* @access public
* @return void
*/
public function getc()
{
@socket_set_timeout($this->socket, $this->timeout);
return fgetc($this->socket);
}
/**
* Clears internal command buffer
*
* @access public
* @return void
*/
public function clearBuffer()
{
$this->buffer = '';
}
/**
* Reads characters from the socket and adds them to command buffer.
* Handles telnet control characters. Stops when prompt is ecountered.
*
* @access public
* @param string $prompt
* @return bool
*/
public function readTo($prompt)
{
if (!$this->socket)
{
throw new Exception("Telnet connection closed.");
}
$this->clearBuffer();
do
{
$c = $this->getc();
if ($c === FALSE)
{
throw new Exception("Can't find the requested prompt: ".$prompt);
}
if ($c == $this->IAC)
{
if ($this->negotiateTelnetOptions())
{
continue;
}
}
$this->buffer .= $c;
if (substr($this->buffer, -10) == " --More-- ")
{
$this->write(NULL, TRUE, FALSE);
}
elseif (@preg_match($prompt, $this->buffer))
{
return self::TELNET_OK;
}
}
while ($c != $this->NULL OR $c != $this->DC1);
}
/**
* Write command to a socket
*
* @access public
* @param string $buffer Stuff to write to socket
* @param bool $addNewLine Default true, adds newline to the command
* @param bool $clearBuffer Default true, clear buffer from last command
* @return bool
*/
public function write($buffer = '', $addNewLine = TRUE, $clearBuffer = TRUE)
{
if (!$this->socket)
{
throw new Exception("Telnet connection closed.");
}
if ($clearBuffer)
{
$this->clearBuffer();
}
if ($addNewLine == TRUE)
{
$buffer .= $this->CR;
}
if (!fwrite($this->socket, $buffer) < 0)
{
throw new Exception("Error writing to socket.");
}
return self::TELNET_OK;
}
/**
* Returns the content of the command buffer
*
* @access public
* @return string Content of the command buffer
*/
public function getBuffer()
{
return $this->buffer;
}
/**
* Telnet control character magic
*
* @access public
* @param string $command Character to check
* @return bool
*/
public function negotiateTelnetOptions()
{
$c = $this->getc();
if ($c != $this->IAC)
{
if (($c == $this->DO) OR ($c == $this->DONT))
{
$opt = $this->getc();
fwrite($this->socket, $this->IAC.$this->WONT.$opt);
}
else if (($c == $this->WILL) OR ($c == $this->WONT))
{
$opt = $this->getc();
fwrite($this->socket, $this->IAC.$this->DONT.$opt);
}
}
else
{
throw new Exception('Error: Something Wicked Happened.');
}
return self::TELNET_OK;
}
/**
* Reads socket until prompt is encountered
*
* @access public
*/
public function waitPrompt()
{
return $this->readTo($this->prompt);
}
}
/* End of file */
答案 0 :(得分:0)
如果你知道提示将是&#34; C:\ Users \ XX&#34;,你可以使用
setprompt("/^C:\\\\Users\\\\XX>/");
答案 1 :(得分:-1)
我可以使用setprompt()来设置提示,因为我期待它,&#34; C:\ Users \ XX&gt;&#34;例如 。我试着像setpromot(&#39; C:\ Users \ XX&gt;&#39;)如果我将使用setprompt()方法它不起作用。我必须把它放在代码中? 。这是我用来测试类
的代码<?php
include "telnet_class_2.php";
$telnet = new Telnet ('192.168.1.xx');
$telnet->login('Jusername' , 'password');
$result = $telnet->exec('dir');
$telnet->exec('exit');
echo $result;
?>