php telnet类在特殊字符处停止读取>;和%


php telnet class stop reading at special characters > and %

我使用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 */ 

如果您知道提示将是"C:''Users''XX",您可以使用

setprompt("/^C:''''Users''''XX>/");

我可以使用setprompt()来设置我期望的提示吗,例如"C:''Users''XX>"。我像setpromot('C:''Users''XX>')一样尝试了它,如果我使用方法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;
?>