Jump to content

PHP socket functions not putting certain chars through, and more!


aximbigfan

Recommended Posts

Hi,

 

I have a little pet project of mine, which is a PHP socket server and API. Don't ask me why I'm building it, because I have no idea. It is fun or something I guess.

 

Now, I have two problems.

 

1. If a "{" by itself is passed through nothing comes back. IF a "{" is sent through with something in front of it (like this: "a{") it works perfectly. The same goes with "[" and literally two quotes ("").

 

2. This one is strange. If I put more than 2 writes to the socket on the API side, it doesn't work at all. It will freeze up on "reading content data... ".

 

Here is the source code---------------------

 

First, here is the server.

#!/usr/bin/php -q
<?php
//SocketServer
//A PHP app to RX/TX data via sockets
//Written by Chris S
$ver = "1.4S";

//Set time out to infinite
set_time_limit(0);

//Set ob_implicit_fluish off
ob_implicit_flush(false);

//Custom encoding function
function safe_encode($mode, $input)
{	
if ($mode == "TX")
	return rawurlencode(json_encode($input));
else if ($mode == "RX")
	return json_decode(rawurldecode($input));
else
	return false;
}

//Function to load options
function load_options()
{
global $config, $opt_address, $opt_port, $opt_pass;
@$config       = parse_ini_file("config.ini");
@$opt_address  = $config["opt_address"];
@$opt_port     = $config["opt_port"];
@$opt_pass     = $config["opt_pass"];
if ($config)
return true;
else
return false;
}

//Opening information
echo "\n*** SocketServer, Version: $ver ***\n";

//Load options and report
echo "Loading configuraion...        ";
if (!load_options())
die("Error!\n");
else
echo "OK\n";

//Check options and report
echo "Checking options...            ";
if ($opt_address == NULL || $opt_port == NULL)
die("Error!\n");
else
echo "OK\n";

//Create socket and report
echo "Creating Socket...             ";
$socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!$socket)
die("Error!\n");
else
echo "OK\n";

//Bind the socket and report
echo "Binding socket...              ";
if (!@socket_bind($socket, $opt_address, $opt_port))
die("Error!\n");
else
echo "OK\n";

//Start listening for connections and report
echo "Listening for connections...   ";
if (!@socket_listen($socket))
die("Error!\n");
else
echo "OK\n";

//Space out
echo "\n";

//Information
echo "  Startup Complete.\n";
echo "  Contact On Port $opt_port @ $opt_address \n";

//Mark the end of startup messages
echo "--------------------------------------------------\n";

//Connections
while (true)
{

//Accept new connection
$spawn           = socket_accept($socket);
if ($spawn)
	echo "-- New connection accepted!\n";
else
	echo "-- Error accepting new connection.\n";

//Read sent data and report
echo "Reading type data...       ";
$type = socket_read($spawn, 10000);
if (!$type)
	echo "Error!\n";
else
	echo "OK\n";

//Split type string into auth and type
$type_1 = explode(",", $type);
$auth   = $type_1[0];
$type   = $type_1[1];

echo "Authenticating...          ";
if (trim($auth)!=$opt_pass)
{
	echo "Error!\n\n";
	socket_close($spawn);
	continue;
}
else
	echo "OK\n";

//Read sent data and report
echo "Reading content data...    ";
$input = socket_read($spawn, 100000);
if (!$input)
	echo "Error!\n";
else
	echo "OK\n";

//Trim incomming
$type   = trim($type);
$input  = trim($input);

//Decode recived data
$type  = safe_encode("RX", $type);
$input = safe_encode("RX", $input);

//Configure types
switch ($type)
{
	case "CONTENT": //For communication
	$input = $input;
	break;

	case "COMMAND": //For commands
	switch (strtoupper($input))
	{
		//Shutdown
		case "SHUTDOWN":
		echo "Shutdown signal given. Shutting down...\n";
		socket_close($spawn);
		socket_close($socket);
		die;
		break;

		//Reload options
		case "RELOAD":
		echo "Reload signal given. Reloading settings... ";
		if (!load_options())
			echo "Error!\n\n";
		else
			echo "OK\n\n";
		socket_close($spawn);
		$mark_continue = true;
		break;

		//Unknown
		default:
		echo "Client submitted unknown command\n\n";
		socket_close($spawn);
		$mark_continue = true;
		break;
	}
	break;
}

//Test if continue
if ($mark_continue)
continue;

//Decode input
$input = safe_encode("RX", $input);

/////////////////////////
$input = base64_encode($input);

////////////////////////

//Send data to client and report
echo "Sending data to client...  ";
//safe_encode data
$output        = safe_encode("TX", $input);
$write_result  = socket_write($spawn, $output, strlen($output));
	if (!$write_result)
	echo "Error!\n";
else
	echo "OK\n";

//Space out
echo "\n";

//Close connection
socket_close($spawn);
}

?>

 

Here is the configuration file for the server

;SocketServer Options
opt_address     = "192.168.15.111"
opt_port        = "1337"
opt_pass        = "033bd94b1168d7e4f0d644c3c95e35bf"

 

Next, we have the API

<?php
//SocketClientAPI
//A PHP app to RX/TX data via sockets
//Written by Chris S
$ver = "1.2S";

class socketClient
{

//Construct function
public function __construct($opt_address, $opt_port, $opt_pass=NULL)
{
//If one or both of the fields is not filled out, return false
if ($opt_address == NULL || $opt_port == NULL)
	return false;
//Set the variables for the socketClient() function
$this->opt_address  = $opt_address;
$this->opt_port     = $opt_port;
$this->opt_pass     = $opt_pass;
}

//Function to return the last status code given; maybe a falure message
public function socketClient_error()
{
//This is a temp fix to the undefind variable warning in the error log
@$lasterror = $this->last_error;
return $lasterror;
}

//Main function
public function socketClient($data, $mode=NULL)
{
//Load pass as std variable
$pass      = md5($this->opt_pass);
//Encode data for safe travel
$data      = rawurlencode(json_encode($data));
//Open the connection to the server
$handle    = fsockopen($this->opt_address, $this->opt_port);
//If the output of fsockopen() failed, return false
if (!$handle)
{
	$this->last_error = "no_open";
	return false;
}
//Cofigure types
if (isset($mode))
	$type  = strtoupper($mode);
else
	$type  = "CONTENT";
//Send data and test
if (!fwrite($handle, "$pass,$type"))      //Type
	$this->last_error = "type_unsent";
if (!fwrite($handle, $data))              //Body
	$this->last_error = "body_unsent";
//Get the socket's output and test
$output    = stream_get_contents($handle);
if (!$output)
	$this->last_error = "no_get";
//Close socket
fclose($handle);
//Return decoded output
return json_decode(rawurldecode($output));
}
}

?>

 

 

And here is an example that uses the socketClient API

<?php
include "SocketClient.php";

@$input = $_POST["input"];
@$type  = $_POST["type"];


if ($input != NULL)
{
$handle = new socketClient("192.168.15.111", 1337, "TEST");
$ret = $handle->socketClient($input, $type);
$le  = $handle->socketClient_error();
echo "$ret";
echo "<br>";
echo  "$le";
}

echo "
<head>
<title>Socketclient Test</title>
</head>
<body>
<html>
	<form method='post'>
		<b>Type:</b><select name='type'>
			<option value='CONTENT'>content</option>
			<option value='COMMAND'>command</value>
		</select><br>
		<b>Send:</b><input type='text' name='input'>
		<input type='submit'>
	</form>
</html>
</body>
";

?>

 

 

Thanks!

 

Chris

 

Link to comment
Share on other sites

Welp, json_decode was the problem. Took EVERYTHING json out, and no more problem.

 

The problem I now have is that I need a way to encode data into plain text, then convert it back again. For some reason serialize and unserialize don't work. Any OTHER functions that aren't serialize that may work?

 

Thanks,

Chris

Link to comment
Share on other sites

What's wrong with serialize() and unserialize()?  Are you encoding binary data or php structures?  What other functions will work depends on what you need from your functions.

 

What I mean by json_encode() and json_decode() not being symmetrical is that json_decode(json_encode($x)) is not always $x.  I am pretty sure that they are NEVER equal when the input to json_encode() is a simple string.

 

 

Link to comment
Share on other sites

The approach I would use there is to add some debugging output.  Instead of this:

 

return rawurlencode(json_encode($input));

 

this:

 

print "Original: $input\n";
$json_enc = json_encode($input);
print "Encoded to $json_enc\n";
$urlencoded = rawurlencode($json_enc);
print "URL encoded to $urlencoded\n";
return $urlencoded;

 

Then you can see at what stage it goes wrong, and fix it.  In the code in the original post, json_decode() returns nothing for all of my test cases, because the output of json_encode() on a string does not result in valid json.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.