PHP socket programming problem - php

I have developed a socket server using C# and a client in PHP which connects fine .. i just need to send some data from the client to the server.
I developed the PHP socket client as according to this Past Stackoverflow Question
<?php
$host="127.0.0.1" ;
$port=9875;
$timeout=30;
$sk=fsockopen($host,$port,$errnum,$errstr,$timeout) ;
if (!is_resource($sk)) {
exit("connection fail: ".$errnum." ".$errstr) ;
} else {
echo "Connected";
}
?>
Finally What i required is to send a data (byte array) to the socket server using this PHP client

fwrite(), see as well the manual page for fsockopen() for examples.
$bytesWritten = fwrite($sk, $string);
If you have an array of bytes, convert it to string before writing:
$string = imlode('', $byteArray);

From the PHP Documentation:
fwrite($sk, 'A message sent to the server');
Or with arrays :
$array = array(4, '3', 'Foo');
fwrite($sk, serialize($array)); //You'll have to deserialize it on C# side.

$msg = "Your message here";
fwrite($sk, $msg);
// Only if you expect some response
while (!feof($sk)) {
echo fgets($sk, 128);
}
// Close the stream
fclose($sk);

Related

Socket_write not working after mysql_query

I'm trying to communicate with my android client to php server using socket. All works great because I can send and receive messages correctly. Now, I need to establish server's action in base of what I sent from the client. In particular there are two possibilities, if I send:
1) "Close" -> I'd like to close the socket with the client and communicate this to it.
2) Other data in form "string"-"string"-"string"-"string"-"string" -> the server has to upload this data to a database mysql and communicate success/failure to client via socket. This is the part of my code needed for the question:
if (strcmp(trim($input),"Close") == 0)
{
//remove and close the socket
echo "close";
socket_write($client_socks[$i] , "communication close");
socket_close($client_socks[$i]);
unset($client_socks[$i]);
}else{
//input -> user-lat-long-accurancy-timestamp
$input = trim($input);
$pieces = explode("-", $input);
$user = $pieces[0];
$latitudine = $pieces[1];
$longitudine = $pieces[2];
$accurancy = $pieces[3];
$timestamp = $pieces[4];
$sql22 = "INSERT INTO `positions` (`unique_id`, `timestamp`, `latitudine`, `longitudine`, `accurancy`) VALUES ('".$user."', '".$timestamp."', '".$latitudine."', '".$longitudine."', '".$accurancy."');";
if ($db->query($sql22)){
echo "ok";
socket_write($client_socks[$i] , "Y");
}else {
echo "ko";
socket_write($client_socks[$i] , "N");
}
}
It does not work because i don't receive the message Y/N. This is an example test of what happens:
Client: Server (on terminal)
"test1-test-test-test-test" ----> echo "ok"
NOTHING <---- socket_write -> Y
"test2-test-test-test-test" ----> echo "ko"
NOTHING <---- socket_write -> N
"Close" ----> echo "close"
"YNcommunication close" <---- socket_write ->communication close
Note that I receive "YN+communication close" and not only "communication close". What happens?
Thanks.

How to receive data from ESP8266 Wifi Module using php

I tried with sending a GET request using ESP8266 wifi module using Arduino.The module successfully responded with :
SEND OK +IPD
On server, I want to receive the data and write it in a text file. So i tried the following codes
>parse_str( html_entity_decode( $_SERVER['QUERY_STRING']) , $out); $data= $out['data'];
$fileStatus=file_put_contents('myFile.txt',$data,FILE_APPEND);
if($fileStatus!=false){
echo "SUCCESS";
} else{ echo "FAIL"; }
But the data failed to store.
Assuming your GET request from the ESP to the server was made to the URL http://example.com/myPhpScript.php?parameter1=xxxx&parameter2=yyyy
you should be able to get the the value of parameter1 and paramter2 like this:
<?php
$p1 = $_GET['parameter1'];
$p2 = $_GET['parameter2'];
$data = $p1.','.$p2;
file_put_contents('myFile.txt',$data,FILE_APPEND);
?>

socket_read() not blocking

Trying to get my socket_read() to block when the data has already been read before.
I need it to wait for the $spawn socket to have new data (can be equal i.e. would like it to read both times when it receives "FE") before it sends again.
How do I get it to block when there isn't any new data?
$i=0;
while ($i<10){
//Read and Parse Client input
$input = strtoupper(bin2hex(socket_read($spawn, 1)));
echo $input . "\n";
//Deal with requests
if ($input == "FE"){ //Server Ping
socket_write($spawn, $ping_packet);
echo "Ping Attempt \n";
} elseif ($input == "02"){ //Handshake Request
socket_write($spawn, $handshake_packet);
echo "Handshake Attempt \n";
} elseif($input == "01"){ //Login Request
socket_write($spawn, $kick_packet);
echo "Login Attempt \n";
}
$i++;
}
You can set the socket to be blocking by using socket_set_block. See socket_select for how to handle a large number of sockets at the same time.
socket_read will return an empty string if no data is ready to be read. To make a blocking read, use socket_recv with the flag MSG_WAITALL.

Can't establish a connection to the server at ws://localhost:8000/socket/server/startDaemon.php. var socket = new WebSocket(host);

I am using javascript to connect websocket:
<script>
var socket;
var host = "ws://localhost:8000/socket/server/startDaemon.php";
var socket = new WebSocket(host);
</script>
I got the error:
Can't establish a connection to the server at
var host = "ws://localhost:8000/socket/server/startDaemon.php";
var socket = new WebSocket(host);
How can I solve this issue?
NOTE : I enabled websocket in mozilla to support web socket application.
and when i run in chrome i got error:
can't establish a connection to the server at ws://localhost:8000/socket/server/startDaemon.php. var socket = new WebSocket(host);
Apparently firefox 4 has websockets disabled because of vulnerabilities. To quote From this article:
WebSocket disabled in Firefox 4
Recent discoveries found that the protocol that Websocket works with is vulnerable to attacks. Adam Barth demonstrated some serious attacks against the protocol that could be used by an attacker to poison caches that sit in between the browser and the Internet.
I solved my error by following code through this link
http://www.flynsarmy.com/2010/05/php-web-socket-chat-application/
and created socketWebSocketTrigger.class.php file for response message where code as
class socketWebSocketTrigger
{
function responseMessage($param)
{
$a = 'Unknown parameter';
if($param == 'age'){
$a = "Oh dear, I'm 152";
}
if($param == 'hello'){
$a = 'hello, how are you?';
}
if($param == 'name'){
$a = 'my name is Mr. websocket';
}
if($param == 'today'){
$a = date('Y-m-d');
}
if($param == 'hi'){
$a = 'hi there';
}
return $a;
}
}
and added code in send function of 'WebSocketServer.php' for calling 'responseMessage' function which response request message
public function send($client, $msg){
$this->say("> ".$msg);
$messageRequest = json_decode($msg,true);
// $action=$messageRequest[0];
$action = 'responseMessage';
$param = $messageRequest[1]['data'];
if( method_exists('socketWebSocketTrigger',$action) ){
$response = socketWebSocketTrigger::$action($param);
}
$msg = json_encode(
array(
'message',
array('data' => $response)
)
);
$msg = $this->wrap($msg);
socket_write($client, $msg, strlen($msg));
}
it's working great.
Are you trying to run the client in Firefox? According to the documentation:
As of Feb/10 the only browsers that
support websockets are Google Chrome
and Webkit Nightlies. Get it from here
http://www.google.com/chrome
Try running it in Chrome and see if that works for you.
First of all your mistake is using php function with javascript require_once 'WebSocket.php'; and secondly go through the tutorial as in the link below.
http://net.tutsplus.com/tutorials/javascript-ajax/start-using-html5-websockets-today/
it's working fine.
Thanks,

php telnet no response from script

I'm running PHP5 on Windows XP Professional. I'm trying to write a telnet php script which simply connects, sends a text string and grabs the response buffer and outputs it. I'm using the telnet class file from here:
http://cvs.adfinis.ch/cvs.php/phpStreamcast/telnet.class.php
which i found in another thread.
<?php
error_reporting(255);
ini_set('display_errors', true);
echo "1<br>";
require_once("telnet_class.php");
$telnet = new Telnet();
$telnet->set_host("10.10.5.7");
$telnet->set_port("2002");
$telnet->connect();
//$telnet->wait_prompt();
$telnet->write('SNRD 1%0d');
echo "3<br>";
$result = $telnet->get_buffer();
echo $result;
print_r($result);
// flush_now();
echo "4<br>";
$telnet->disconnect();
?>
I'm not receiving any kind of errors or response. If I send an invalid string, I should get an 'ERR' response in the least however I don't even get that. Any ideas what i could be doing wrong? If I do the same thing from the command prompt, I receive the string output I need. Could this is because the write function is sending
After some reading in the source code and on the original (french) site referred to in the header....
<?php
error_reporting(255);
ini_set('display_errors', true);
echo "1<br>";
require_once("telnet_class.php");
$telnet = new Telnet();
$telnet->set_host("10.10.5.7");
$telnet->set_port("2002");
if ($telnet->connect() != TELNET_OK) {
printf("Telnet error on connect, %s\n",$telnet->get_last_error());
}
//$telnet->wait_prompt();
if ($telnet->write('SNRD 1' . "\xd") != TELNET_OK) {
printf("Telnet error on write, %s\n",$telnet->get_last_error());
}
// read to \n or whatever terminates the string you need to read
if ($telnet->read_to("\n") != TELNET_OK) {
printf("Telnet error on read_to, %s\n",$telnet->get_last_error());
}
echo "3<br>";
$result = $telnet->get_buffer();
echo $result;
print_r($result);
// flush_now();
echo "4<br>";
$telnet->disconnect();
?>
Okay, explanation: get_buffer() does just that, read what's in the buffer. To get something in the buffer you have to execute read_to($match) who will read into buffer up to $match. After that, get_buffer should give you the desired string.
EDIT:
if you cannot find some string that follows the string you are interested in read_to will end in an error due to this part of the read_to method (translation of original french comment is mine):
if ($c === false){
// plus de caracteres a lire sur la socket
// --> no more characters to read on the socket
if ($this->contientErreur($buf)){
return TELNET_ERROR;
}
$this->error = " Couldn't find the requested : '" . $chaine . "', it was not in the data returned from server : '" . $buf . "'" ;
$this->logger($this->error);
return TELNET_ERROR;
}
Meaning that when the socket is closed without a match of the requested string, TELNET_ERROR will be returned. However, the string you're looking for should at that point be in the buffer.... What did you put in read_to's argument? "\n" like what I did or just "" ?
EDIT2 :
there's also a problem with get_buffer. IMO this class is not really a timesaver ;-)
//------------------------------------------------------------------------
function get_buffer(){
$buf = $this->buffer;
// cut last line (is always prompt)
$buf = explode("\n", $buf);
unset($buf[count($buf)-1]);
$buf = join("\n",$buf);
return trim($buf);
}
It will throw away the last line of the response, in your case the one that contains the
answer.
I suggest to add a "light" version of get_buffer to the class, like this
//------------------------------------------------------------------------
function get_raw_buffer(){
return $this->buffer;
}
and do the necessary trimming/searching in the result yourself.
You might also want to add the following constant
define ("TELNET_EOF", 3);
and change read_to like this
...
if ($c === false){
// plus de caracteres a lire sur la socket
if ($this->contientErreur($buf)){
return TELNET_EOF;
}
$this->error = " Couldn't find the requested : '" . $chaine . "', it was not in the data returned from server : '" . $buf . "'" ;
$this->logger($this->error);
return TELNET_EOF;
}
...
in order to treat that special case yourself (a result code TELNET_EOF doesn't have to be treated as an error in your case). So finally your code should look more or less like this:
// read to \n or whatever terminates the string you need to read
if ($telnet->read_to("\n") == TELNET_ERROR) {
printf("Telnet error on read_to, %s\n",$telnet->get_last_error()); } echo "3<br>";
} else {
$result = $telnet->get_raw_buffer();
echo $result;
print_r($result);
}
Have you checked how the telnet class works? Maybe it wasn't designed to run under windows. If it's a simple socket that you're speaking to, maybe consider using a regular socket-connection instead.
http://se2.php.net/sockets
If you open up a socket which you don't close, you should se an entry in netstat as long as your script is running.
netstat -na|find ":2002"
You can't insert hex values like that. The remote process just sees
SRND 1%0d
and now it's waiting for the line to be terminated. Try this
$telnet->write('SNRD 1' . "\r");
or
$telnet->write("SNRD 1\xd");
The double quotes are quite critical, see here
EDIT:
you might try adding some error reporting as right now you don't really check much (error_reporting won't show anything on the errors in the telnet class).... For example:
<?php
error_reporting(255);
ini_set('display_errors', true);
echo "1<br>";
require_once("telnet_class.php");
$telnet = new Telnet();
$telnet->set_host("10.10.5.7");
$telnet->set_port("2002");
if ($telnet->connect() != TELNET_OK) {
printf("Telnet error on connect, %s\n",$telnet->get_last_error());
}
//$telnet->wait_prompt();
if ($telnet->write('SNRD 1' . "\xd") != TELNET_OK) {
printf("Telnet error on write, %s\n",$telnet->get_last_error());
}
echo "3<br>";
$result = $telnet->get_buffer();
echo $result;
print_r($result);
// flush_now();
echo "4<br>";
$telnet->disconnect();
?>
also, are you sure you need \r\n line termination? write is defined as
function write($buffer, $valeurLoggee = "", $ajouterfinLigne = true){
and does
if ($ajouterfinLigne){
$buffer .= "\n";
}
?
Also, did you test the host and port with the command line telnet client? Like
telnet 10.10.5.7 2002
?

Categories