Image

Imageskywayman wrote in Imagephp

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.



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.'
'; }