Socket problem
I've got a class I'm writing (PHP5) that has three methods:
1) Connect to a remote machine
2) Send a command (and read response)
3) Disconnect from the remote machine
When I connect to the remote machine and log in to the system I'm golden, but after I return from the method and try to send another command, it never gets there. I watched the socket traffic on the remote machine and the second command never gets there. My script returns no errors, but times out waitng for a remote response.
If ya'll got some time, I'd appreciate the help.
Here is how I call it:
1) Connect to a remote machine
2) Send a command (and read response)
3) Disconnect from the remote machine
When I connect to the remote machine and log in to the system I'm golden, but after I return from the method and try to send another command, it never gets there. I watched the socket traffic on the remote machine and the second command never gets there. My script returns no errors, but times out waitng for a remote response.
If ya'll got some time, I'd appreciate the help.
class cpAdmin
{
var $hostname; // Host or IP to connect to
var $port; // Port to connect on
var $timeout; // Port connect timeout
var $password; // Password to use
var $cprw; // Read/write or Read-only
const cpeol = '\r\n'; // End of Line for the remote commands
var $command; // Command to send to the host
var $okerror; // OK or ERROR from the host
var $cperror; // ERROR message from the host
var $cpresult; // Server data response (array)
var $cpresultc; // "clean" Server data response (array) stripped of all special markers, line feeds, etc.
var $cpcommand; // Command to send to host
var $socket; // Socket connection
var $answer; // data read from from the socket
var $connected; // 1 or 0, is the socket connected?
var $loggedin; // 1 or 0, are we logged in?
var $enable; // 1 or 0, do we have enabled privs?
var $gerror; // General Error (for non server communications errors)
var $gerrord; // General Error Description
// Connect and log in.
function connect()
{
$this->connected = 0;
$this->gerror = 0;
$this->loggedin = 0;
if(!$this->socket = fsockopen($this->hostname, $this->port, $errno, $errstr, $this->timeout))
{
$this->gerrord = "Error connecting to the socket! Error Number: " . $errno . " Error description: " . $errstr;
$this->gerror = 1;
return FALSE;
}
else
{
$this->gerror = 0;
// Set the stream to blocking so we can read multiple lines from it if we need to.
/*
http://us3.php.net/manual/en/function.stream-set-blocking.php
If mode is 0, the given stream will be switched to non-blocking
mode, and if 1, it will be switched to blocking mode. This affects
calls like fgets() and fread() that read from the stream. In
non-blocking mode an fgets() call will always return right away
while in blocking mode it will wait for data to become available on
the stream.
*/
if(!stream_set_blocking($this->socket, TRUE))
{
$this->gerror = 1;
$this->gerrord = 'Error setting the socket stream to blocking mode';
return FALSE;
}
// Read the answer from the connection and see if we connected right. We read in 128 bytes. Don't
// read to EOL, it won't work with the CP servers.
$this->answer = fgets($this->socket,512);
if(!preg_match("/\<.+\@.+\.com>/", $this->answer))
{
// If this fails you are probably not set to blocking on the stream or you did not read enough in.
$this->gerror = 1;
$this->gerrord = 'Data read from the stream did not look like a CP initialization string';
return FALSE;
}
else
{
$this->cperror = $this->answer;
}
// Log in.
if($this->cprw == "rw")
{
$loginString = "LOGIN $this->password WRITE\r\n";
$this->enable = 1;
}
else
{
$loginString = "LOGIN $this->password\r\n";
$this->enable = 0;
}
if(!fputs($this->socket, $loginString.cpAdmin::cpeol))
{
$this->gerror = 1;
$this->gerrord = 'Error writing to socket. Not connected?';
return FALSE;
}
$this->answer = fgets($this->socket,64);
if(preg_match("/^ERROR/",$this->answer))
{
$this->gerror = 0;
$this->okerror = "ERROR";
$this->connected = 1;
}
elseif(preg_match("/^OK/",$this->answer))
{
$this->gerror = 0;
$this->loggedin = 1;
$this->okerror = "OK";
$this->cperror = $this->answer;
$this->connected = 1;
}
}
return TRUE;
}
function disconnect()
{
// Disconnect
$this->okerror = '';
$this->cperror = '';
$this->gerror = 0;
if($this->connected == 0)
{
$this->gerror = 1;
$this->gerrord = 'Socket is not connected.';
return FALSE;
}
if(!fputs($this->socket, 'QUIT'.cpAdmin::cpeol))
{
$this->gerror = 1;
$this->gerrord = 'Error writing to socket. Not connected?';
return FALSE;
}
@fclose ($this->socket);
$this->connected = 0;
return TRUE;
}
function command()
{
$this->gerror = 0;
$this->okerror = "";
$this->cperror = "";
if($this->connected == 0)
{
$this->gerror = 1;
$this->gerrord = 'Socket is not connected.';
return FALSE;
}
$count = 0;
$command = $this->cpcommand.'\r\n';
if(!fputs($this->socket, $command))
{
$this->gerror = 1;
$this->gerrord = 'Error writing to socket. Not connected?';
return FALSE;
}
while($answer = fgets($this->socket,128))
{
echo $answer.'
';
if((!preg_match('/^ERROR/',$answer)) && (!preg_match('/^OK/',$answer)))
{
$this->cpresult[$count] = $answer;
$this->cpresultc[$count] = preg_replace('* ','', rtrim($answer));
$count++;
}
elseif(preg_match('/^OK/',$answer))
{
$this->okerror = 'OK';
}
elseif(preg_match('/^ERROR/',$answer))
{
$this->okerror = 'ERROR';
$this->cperror = $answer;
}
}
return TRUE;
}
}
Here is how I call it:
include "cpAdmin.inc";
$bob = new cpAdmin();
$bob->hostname = '1.2.3.4';
$bob->port = '1234';
$bob->timeout = '30';
$bob->password = 'somepassword';
$bob->cprw = 'ro';
if($bob->connect())
{
echo 'Connected: '.$bob->connected.'
';
echo 'OK/ERROR from host: '.$bob->okerror.'
';
echo 'CP ERROR msg: '.$bob->cperror.'
';
echo 'Logged in?: '.$bob->loggedin.'
';
$bob->cpcommand = 'SOME COMMAND';
if(!$bob->command())
{
echo '
problem sending command
';
echo 'Gen. Erorr desc: '.$bob->gerrord.'
';
echo 'Gen error y/n: '.$bob->gerror.'
';
}
else
{
echo '
command result:
';
echo "result: ".$bob->cpresult.'
';
}
}
else
{
echo 'Connected: '.$bob->connected.'
';
echo 'OK/ERROR from CP: '.$bob->okerror.'
';
echo 'CP ERROR msg: '.$bob->cperror.'
';
echo 'Gen. Erorr desc: '.$bob->gerrord.'
';
echo 'Gen error y/n: '.$bob->gerror.'
';
}
