bestnetwork/telnet
bestnetwork/telnet is a lightweight Telnet client library for PHP, providing basic tools to connect to Telnet servers and send/receive commands over a Telnet session. Suitable for simple automation, diagnostics, and interacting with legacy network services.
Install the Package:
composer require bestnetwork/telnet
Basic Connection:
use BestNetwork\Telnet\Telnet;
$telnet = new Telnet('192.168.1.1', 23); // Host and port
$telnet->connect();
$telnet->write('login');
$response = $telnet->read();
$telnet->disconnect();
First Use Case: Automate a login sequence for a legacy device:
$telnet = new Telnet('legacy-device.local', 23);
$telnet->connect();
$telnet->write('username');
$telnet->write('password');
$output = $telnet->readUntil('>'); // Read until prompt
logger()->info('Login output:', ['output' => $output]);
$telnet->disconnect();
src/Telnet.php – Contains connect(), write(), read(), and disconnect() methods.tests/ – Example usage and edge cases (e.g., timeouts, malformed responses).Service Container Binding:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->bind(Telnet::class, function () {
return new Telnet(config('telnet.host'), config('telnet.port'));
});
}
Artisan Command:
// app/Console/Commands/CheckDevice.php
use BestNetwork\Telnet\Telnet;
protected $telnet;
public function __construct(Telnet $telnet)
{
$this->telnet = $telnet;
}
public function handle()
{
$this->telnet->connect();
$this->telnet->write('status');
$response = $this->telnet->readUntil('OK');
$this->info($response);
$this->telnet->disconnect();
}
Queueable Job:
// app/Jobs/SendTelnetCommand.php
use BestNetwork\Telnet\Telnet;
use Illuminate\Bus\Queueable;
public function handle(Telnet $telnet, string $command)
{
$telnet->connect();
$telnet->write($command);
$response = $telnet->readUntil('>');
// Store or process response
$this->storeResponse($response);
}
Login and Command Execution:
$telnet = new Telnet('device.ip', 23);
$telnet->connect();
$telnet->write('login');
$telnet->write('admin');
$telnet->write('secret');
$telnet->write('show config');
$config = $telnet->readUntil('prompt>');
$telnet->disconnect();
Timeout Handling:
$telnet->setTimeout(10); // 10-second timeout
try {
$telnet->write('slow-command');
$response = $telnet->readUntil('OK', 15); // 15-second read timeout
} catch (\Exception $e) {
logger()->error('Telnet timeout:', ['error' => $e->getMessage()]);
}
Response Parsing:
$output = $telnet->read();
preg_match('/Version: (\d+\.\d+)/', $output, $matches);
$version = $matches[1] ?? 'unknown';
$telnet = resolve(Telnet::class);
$telnet->connect();
// config/telnet.php
return [
'devices' => [
'router' => ['host' => '192.168.1.1', 'port' => 23],
'switch' => ['host' => '192.168.1.2', 'port' => 23],
],
];
use React\EventLoop\Factory;
use BestNetwork\Telnet\Telnet;
$loop = Factory::create();
$telnet = new Telnet('device.ip', 23);
$loop->futureTick(function () use ($telnet) {
$telnet->connect();
$telnet->write('status');
$response = $telnet->readUntil('>');
echo $response;
$telnet->disconnect();
});
$loop->run();
Blocking I/O:
spatie/async-command or react/async for async operations.No Native Error Handling:
Illuminate\Support\Facades\Log or custom exceptions.try {
$telnet->write('invalid-command');
} catch (\Exception $e) {
throw new \RuntimeException("Telnet error: {$e->getMessage()}");
}
Telnet Protocol Limitations:
phpseclib/phpseclib) or VPNs for secure communication.Connection Leaks:
disconnect() can exhaust system resources.finally block or Laravel’s ensureClosure:
$telnet->connect();
try {
$telnet->write('command');
} finally {
$telnet->disconnect();
}
Timeout Quirks:
setTimeout().$telnet->setTimeout(30); // 30-second timeout
Enable Verbose Logging:
$telnet->setDebug(true); // If supported (check package docs)
logger()->debug('Telnet output:', ['raw' => $telnet->read()]);
Mock Telnet for Testing:
// Use a test double or socat for local testing
$telnet = Mockery::mock(Telnet::class);
$telnet->shouldReceive('read')->andReturn('mocked response');
Check for EOF:
$telnet->eof() before reading to avoid hanging.while (!$telnet->eof()) {
$data = $telnet->read(1024);
if (empty($data)) break;
}
Custom Response Parsers:
class EnhancedTelnet extends Telnet {
public function parseVersion($output) {
preg_match('/Version: (\d+\.\d+)/', $output, $matches);
return $matches[1] ?? null;
}
}
Retry Middleware:
use Illuminate\Support\Facades\Retry;
Retry::retry(3, function () use ($telnet) {
$telnet->connect();
$telnet->write('command');
$response = $telnet->readUntil('OK');
return $response;
}, 1000); // 1-second delay between retries
Laravel Service Provider:
// Register a custom Telnet instance
$this->app->singleton('custom.telnet', function () {
$telnet = new Telnet(config('telnet.host'));
$telnet->setTimeout(15);
return $telnet;
});
23. Override explicitly:
$telnet = new Telnet('host', 2323); // Custom port
class TelnetPool {
private $connections = [];
public function get($host) {
if (!isset($this->connections[$host])) {
$this->connections[$host] = new Telnet($host);
}
return $this->connections[$host];
}
}
config/credentials.phpHow can I help you explore Laravel packages today?