Socket problem

    Date: 09/07/05 (PHP Community)    Keywords: php

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

    Source: http://www.livejournal.com/community/php/342193.html

« for chrissakes || PHP 4 str_split »


antivirus | apache | asp | blogging | browser | bugtracking | cms | crm | css | database | ebay | ecommerce | google | hosting | html | java | jsp | linux | microsoft | mysql | offshore | offshoring | oscommerce | php | postgresql | programming | rss | security | seo | shopping | software | spam | spyware | sql | technology | templates | tracker | virus | web | xml | yahoo | home