aximbigfan Posted August 12, 2008 Share Posted August 12, 2008 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 https://forums.phpfreaks.com/topic/119406-php-socket-functions-not-putting-certain-chars-through-and-more/ Share on other sites More sharing options...
btherl Posted August 13, 2008 Share Posted August 13, 2008 Are you expecting json_encode() and json_decode() to be symmetrical? They're not .. Link to comment https://forums.phpfreaks.com/topic/119406-php-socket-functions-not-putting-certain-chars-through-and-more/#findComment-615205 Share on other sites More sharing options...
aximbigfan Posted August 13, 2008 Author Share Posted August 13, 2008 I'm just wanted then to encode then decode arrays and such. How are they not symmetrical? Chris Link to comment https://forums.phpfreaks.com/topic/119406-php-socket-functions-not-putting-certain-chars-through-and-more/#findComment-615222 Share on other sites More sharing options...
aximbigfan Posted August 13, 2008 Author Share Posted August 13, 2008 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 https://forums.phpfreaks.com/topic/119406-php-socket-functions-not-putting-certain-chars-through-and-more/#findComment-615228 Share on other sites More sharing options...
btherl Posted August 13, 2008 Share Posted August 13, 2008 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 https://forums.phpfreaks.com/topic/119406-php-socket-functions-not-putting-certain-chars-through-and-more/#findComment-615237 Share on other sites More sharing options...
aximbigfan Posted August 13, 2008 Author Share Posted August 13, 2008 For some reason when I change it to serialize the input rather than json it, no input comes back. The socket server is an HP MediaVault running Debian etch and PHP 5.2.6 and the other server is Windows XP pro with PHP 5.2.6 Chris Link to comment https://forums.phpfreaks.com/topic/119406-php-socket-functions-not-putting-certain-chars-through-and-more/#findComment-615241 Share on other sites More sharing options...
btherl Posted August 13, 2008 Share Posted August 13, 2008 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 https://forums.phpfreaks.com/topic/119406-php-socket-functions-not-putting-certain-chars-through-and-more/#findComment-615242 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.