php telnet 远程三层交换机或核心路由器以及服务器

host = $host;
        $this->port = $port;
        $this->timeout = $timeout;

        $this->setStreamTimeout($stream_timeout);
        // set some telnet special characters
        $this->NULL = chr(0);
        $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->connect();
    }

    /**
     * Destructor. Cleans up socket connection and command buffer
     *
     * @return
     * @throws  \Exception
     */
    public function __destruct() {
        // clean up resources
        $this->disconnect();
        $this->buffer = NULL;
        $this->global_buffer = NULL;
    }

    /**
     * Attempts connection to remote host. Returns TRUE if successful.
     *
     * @return boolean
     * @throws \Exception
     */
    public function connect()
    {
        // check if we need to convert host to IP
        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;
            }
        }
        // attempt connection - suppress warnings
        $this->socket = @fsockopen($this->host, $this->port, $this->errno, $this->errstr, $this->timeout);
        if (!$this->socket) {
            throw new \Exception("Cannot connect to $this->host on port $this->port");
        }

        return self::TELNET_OK;
    }

    /**
     * Closes IP socket
     *
     * @return boolean
     * @throws \Exception
     */
    public function disconnect()
    {
        if ($this->socket) {
            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
     *
     * @param string $command Command to execute
     * @param boolean $add_newline Default TRUE, adds newline to the command
     * @return string Command result
     * @throws \Exception
     */
    public function exec($command, $add_newline = true)
    {
        $this->write($command, $add_newline);
        $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
     *
     * @param string $username Username
     * @param string $password Password
     * @throws \Exception
     * @return boolean
     */
    public function login($username, $password)
    {
        try {
            $this->waitPrompt();
            $this->write($username);
            $this->waitPrompt();
            $this->write($password);
            $this->waitPrompt();
        } catch (\Exception $e) {
            throw new \Exception("Login failed: ".$e->getMessage());
        }
        return self::TELNET_OK;
    }


    /**
     * Sets the stream timeout.
     *
     * @param float $timeout
     * @return void
     */
    public function setStreamTimeout($timeout)
    {
        $this->stream_timeout_usec = (int)(fmod($timeout, 1) * 1000000);
        $this->stream_timeout_sec = (int)$timeout;
    }


    /**s
     * Gets character from the socket
     */
    protected function getc()
    {
        stream_set_timeout($this->socket, $this->stream_timeout_sec, $this->stream_timeout_usec);
        $c = fgetc($this->socket);
        $this->global_buffer .= $c;
        return $c;
    }

    /**
     * Clears internal command buffer
     *
     * @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.
     *
     * @param string $prompt
     * @return boolean
     * @throws \Exception
     */
    protected function readTo($prompt)
    {
        if (!$this->socket) throw new \Exception("Telnet connection closed");

        $this->clearBuffer();
        $until_t = time() + $this->timeout;

        do {
            // time's up (loop can be exited at end or through continue!)
            if (time() > $until_t) {
                throw new \Exception("Couldn't find the requested : '$prompt' within {$this->timeout} seconds");
            }
            $c = $this->getc();

            if ($c === false) {
                if (empty($prompt)) return self::TELNET_OK;
                throw new \Exception("Couldn't find the requested : '" . $prompt . "', it was not in the data returned from server: " . $this->buffer);
            }
            // Interpreted As Command
            if ($c == $this->IAC) {
                if ($this->negotiateTelnetOptions()) {
                    continue;
                }
            }
            // append current char to global buffer
            $this->buffer .= $c;


        } while ($c != $this->NULL || $c != $this->DC1);
    }


    /**
     * Write command to a socket
     *
     * @param string $buffer Stuff to write to socket
     * @param boolean $newline Default TRUE, adds newline to the command
     * @return boolean
     * @throws  \Exception
     */
    protected function write($buffer, $newline = true)
    {
        if (!$this->socket) throw new \Exception("Telnet connection closed");

        // clear buffer from last command
        $this->clearBuffer();
        if ($newline) $buffer .= "\n";

        $this->global_buffer .= $buffer;

        if (!fwrite($this->socket, $buffer) < 0) throw new \Exception("Error writing to socket");

        return self::TELNET_OK;
    }

    /**
     * Returns the content of the command buffer
     *
     * @return string Content of the command buffer
     */
    protected function getBuffer()
    {
        // Remove all carriage returns from line breaks
        $buf =  preg_replace('/\r\n|\r/', "\n", $this->buffer);
        // Cut last line from buffer (almost always prompt)
        if ($this->strip_prompt) {
            $buf = explode("\n", $buf);
            unset($buf[count($buf) - 1]);
            $buf = implode("\n", $buf);
        }
        return trim($buf);
    }

    /**
     * Returns the content of the global command buffer
     *
     * @return string Content of the global command buffer
     */
    public function getGlobalBuffer()
    {
        return $this->global_buffer;
    }

    /**
     * Telnet control character magic
     *
     * @return boolean
     * @throws \Exception
     */
    protected function negotiateTelnetOptions()
    {
        $c = $this->getc();
        if ($c != $this->IAC) {
            if (($c == $this->DO) || ($c == $this->DONT)) {
                $opt = $this->getc();
                fwrite($this->socket, $this->IAC . $this->WONT . $opt);
            } else if (($c == $this->WILL) || ($c == $this->WONT)) {
                $opt = $this->getc();
                fwrite($this->socket, $this->IAC . $this->DONT . $opt);
            } else {
                throw new \Exception('Error: unknown control character ' . ord($c));
            }
        } else {
            throw new \Exception('Error: Something Wicked Happened');
        }
        return self::TELNET_OK;
    }

    /**
     * Reads socket until prompt is encountered
     * @return boolean
     * @throws \Exception
     */
    protected function waitPrompt()
    {
        return $this->readTo('');
    }
}

使用案例

$telnet = new Telnet($this->host, $this->port, 10);
$telnet->login($this->username, $this->password);

$commands = explode("\n", $this->content);
$result = '';

foreach ($commands as $key => $item)
{
        $result .= $telnet->exec($item);
}

 

转载于:https://my.oschina.net/u/3054299/blog/3095932

你可能感兴趣的:(php,网络)