Socket_write not working after mysql_query - php

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.

Related

can receive Data After sending through php Sockets

i have a question about Sockets in PHP. My Environment Looks like follows:
one Server VM with Ubuntu 22.04 , and one VM with Windows 10. On The net is Global Cache IP2SL Adapter, on that interface is an Monitor with serial Line connected to this IP2SL.
The Goal should be , to send HEX Codes to the IP2SL which will be send to the Monitor. Some of These Codes have an Answer i.e. some Parameters like Brighness or Situation. In The end , on The Ubuntu is an Website where u can read and change those values . Therefore i've build some small testscripts to Check the Communication. To Monitor the line i use Wireshark, and both VM Linux and Windows run in a Parallels Environment on a Mac.
The Problem:
Did i send the hex code from windows to The IP2SL Adapter, anything looks fine, the command where send to the Monitor and the Monitor answer as expected. Did i send the same via php the command where send , and The Monitor Works with it as expected, if the commmand has no answer, i.e. PowerOn/Poweroff working like a charm, but if the Monitor should send an answer like brightness : XX% there come an "504 gateway TimeOut" After 60s on the Ubuntu System . did i do the same with IP2SL test App , the answer is correctly. In Wireshark is the Communication as expected. my php code Looks like follows
<?php
error_reporting(E_ALL);
ini_set('display_errors',1);
$port = '4999';
$adr = "192.168.100.34";
$sendStr = array('E5', 'TARGET', '20', '86');//hexadecimal data
$target = "05";
function makeValue($v)
{
return pack('H*',dechex($v));
}
function toSend($adr,$port,$target,$cmd)
{
ob_implicit_flush();
// find target
for($i=0;$i < count($cmd);$i++)
{
if($cmd[$i] === "TARGET")
{
$cmd[$i] = hexdec($target);
}
else
{
$cmd[$i] = hexdec($cmd[$i]);
}
}
// build the CRC
$cmd[] = hexdec('FF') - array_sum($cmd) & hexdec('FF');
//var_dump($cmd);
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//socket_set_nonblock($socket);
if ($socket === false) {
echo "socket_create() fehlgeschlagen: Grund: " . socket_strerror(socket_last_error()) . "\n";
} else {
echo "Socket erstellt OK.\r\n";
}
echo "Versuche, zu '$adr' auf Port '$port' zu verbinden ...";
$result = socket_connect($socket, $adr, $port);
if ($result === false) {
echo "socket_connect() fehlgeschlagen.\nGrund: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
} else {
echo "Socket verbunden OK.\r\n";
}
$chars = array_map('makeValue',$cmd);
$out = join($chars);
$length = strlen($out);
//var_dump($out);
if(socket_write($socket, $out,$length))
{
usleep(25000);
$input = stream_get_contents($socket,1024);
socket_close($socket);
var_dump($input);
}
//socket_close($socket);
/*
if($input === FALSE || strcmp($input,'') == 0) {
$code = socket_last_error($socket);
socket_clear_error($socket);
socket_close($socket);
} else {
echo "Answer : ". bin2hex($input);
socket_close($socket);
}
*/
}
toSend($adr,$port,$target,$sendStr);
?>
Solution: The Solution is the array_map function 'makeValue'. The php pack command has an Format 'h*' and 'H*' , if the value is an Single Byte , the 'H*' converts it to the higher nibble , so the value '7' will Converted to '0x70'
function makeValue($v)
{
if(strlen($v)>1)
{
return pack('H*',dechex($v));
}
return pack('h*',dexhex($v));
}
this Solves the Problem

Sending and receiving multiple JSON literals via PHP sockets

I am trying send JSON data from one PHP script to another through sockets. The following is the client code
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
#socket_connect($socket, "localhost", 2429) or die("Connect could not be opened");
$arr = ["Hello", "I", "am", "a", "client"];
$count = 10;
while($count-- > 0) {
$msg = json_encode(["msg" => $arr[rand(0, 4)]]);
// tried appending \n & \0
// $msg .= "\0"; // "\n";
echo "sending $msg \n";
socket_write($socket, $msg, strlen($msg));
}
The following code is a piece of server that handles the reception:
$count = 0;
while(socket_recv($feed, $buf, 1024, 0) >= 1) {
echo "Obj ".++$count." : $buf";
// $obj = json_decode($buf); // error
}
The problem is, on the socket server side, the json_decode is unable to parse the data because of the following situation:
Expected Output:
Obj 1: {"msg":"I"}
Obj 2: {"msg":"a"}
Obj 3: {"msg":"a"}
Obj 4: {"msg":"I"}
Obj 5: {"msg":"a"}
Obj 6: {"msg":"client"}
Obj 7: {"msg":"am"}
Obj 8: {"msg":"am"}
Obj 9: {"msg":"am"}
The output I get:
Obj 1: {"msg":"I"}{"msg":"a"}{"msg":"a"}{"msg":"I"}
Obj 2: {"msg":"a"}{"msg":"client"}{"msg":"am"}{"msg":"am"}
Obj 3: {"msg":"am"}
I understand I need to tell the server end of object before sending the next one, but I do not know how. I tried to append "\n" and "\0" to tell the server end of stream, but it doesn't work. Please help me friends. Thank you in advance!
Let's try adding a length header, as that's the safest way to go when strings are involved.
Your client needs to send that information, so a slight change to your original code is in order: $msg = strlen($msg) . $msg; (right after $msg = json_encode(["msg" => $arr[rand(0, 4)]]);.
Then, assuming $socket is opened, try this as the server code (don't forget to close your sockets):
$lengthHeader = '';
$jsonLiteral = '';
while ($byte = socket_read($socket, 1)) { // reading one number at a time
echo "Read $byte\n";
if (is_numeric($byte)) { //
$lengthHeader .= $byte;
} else if ($lengthHeader) {
echo "JSON seems to start here. So...\n";
$nextMsgLength = $lengthHeader - 1; // except the current one we've just read (usually "[" or "{")
echo "Will grab the next $nextMsgLength bytes\n";
if (($partialJson = socket_read($socket, $nextMsgLength)) === false) {
die("Bad host, bad!");
}
$jsonLiteral = $byte . $partialJson;
$lengthHeader = ''; // reset the length header
echo "Grabbed JSON: $jsonLiteral\n";
} else {
echo "Nothing to grab\n";
}
}
you use socket_write function for other socket. When you add EOF char, is just for other socket recv. But you must know EOF char with that socket_write for your recv and explode it.

PHP and Python unpack return different results from same source

I cannot seem to get even vaguely the same data from the Python (Which I would prefer to use) and PHP (Which works fine, coded by the host of the website) scripts.
PHP connects to the same location as the Python script.
And before anyone jumps the gun, I know the python script only retrieves a part of the data. But I can't get even vaguely the same data from the server.
Python:
import socket, struct
host,port = 'baystation12.net', 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send('status\r\n')
data = s.recv(1024)
s.close()
print 'Received:', repr(data) # >>> Received: '\x00\xc7\x00\x07\x02\xadj\x00\x00\x1c\xf6'
cache,form,listy = "",">H",[]
for i in data:
if cache != "":
listy.append(struct.unpack(form,cache+i))
else:
cache = i
print "Unpacked:",listy # >>> Unpacked: [(199,), (0,), (7,), (2,), (173,), (106,), (0,), (0,), (28,), (246,)]
text = ""
for i in listy:
text += chr(i[0])
print "Text:",text # >>> Text: Ç
#Shows up incorrectly when I try to copy it.
PHP:
#!/usr/bin/php
<?php
function export($addr,$port,$str)
{
if($str{0} != "?") $str = ("?" . $str);
$query = "\x00\x83" . pack("n",strlen($str)+6) . "\x00\x00\x00\x00\x00" . $str . "\x00";
$server = socket_create(AF_INET,SOCK_STREAM,SOL_TCP) or exit('Unable to create export socket; ' . socket_strerror(socket_last_error()));
socket_connect($server,$addr,$port) or exit('Unable to establish socket connection; ' . socket_strerror(socket_last_error()));
$bytessent = 0;
while($bytessent < strlen($query))
{
$result = socket_write($server,substr($query,$bytessent),strlen($query)-$bytessent);
if($result === FALSE) return('Unable to transfer requested data; ' . socket_strerror(socket_last_error()));
$bytessent += $result;
}
$resbuf = '';
while( socket_recv($server, $message,1,0 )){
$resbuf .= $message;
if(strpos($resbuf,"&end")!=FALSE)
{
echo $resbuf;
socket_close($server);
return($resbuf);
}
echo $message;
};
echo $resbuf."\n";
socket_close($server);
}
export("localhost","8000","status");
?>
PHP's output:
version=Baystation+12&mode=extended&respawn=0&enter=1&vote=1&ai=1&host&players=5&player0=CompactNinja&player1=Sick+trigger&player2=SweetJealousy&player3=Cacophony&player4=Anchorshag&end
Any idea why Python gives out nonsensical characters when unpacking the data, while PHP gives out the above.
You're not sending the same query to your server in python.
In python you're sending status
In PHP you're sending something like \x00\x83\x00\x0d\x00\x00\x00\x00\x00\x00?status\x00
If you change your python to more closely imitate the PHP then it works a lot better:
import socket, struct
host,port = 'baystation12.net', 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
senddata = "?status"
query = '\x00\x83' + struct.pack(">H", len(senddata)+6) + '\x00'*5 + senddata + '\x00'
s.send(query)
data = s.recv(1024)
print `data`
When I tried that, it printed
'\x00\x83\x00\xe9\x06version=Baystation+12&mode=traitor&respawn=0&enter=1&vote=1&ai=1&host&players=7&player0=Kosherman&player1=Ghazkull&player2=Doug+H.+Nuts&player3=Lord+Braindead&player4=KirbyElder&player5=Master+of+Apples&player6=Cacophony&end=%23end\x00'
Which looks pretty similar to what the PHP was getting.
Try listy.append(struct.unpack(form,cache+i)[0])
You're ending up with a list of 1-element tuples rather than the a list of numbers.
From the docs: http://docs.python.org/library/struct.html#struct.unpack
struct.unpack(fmt, string)
Unpack the string (presumably packed by
pack(fmt, ...)) according to the given format. The result is a tuple
even if it contains exactly one item. The string must contain exactly
the amount of data required by the format (len(string) must equal
calcsize(fmt)).

PHP socket programming problem

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);

PHP IRC Robot, Send Command, but now I need the bot to read the command

I have a PHP IRC Robot that I use in my channel and I need it to make OPs to specific set users in the script by me. Anyways I want the robot to check if the user is logged into NickServ to prevent any sort of fraud or anything.
Anyways, here is my connect and DO things code, followed by what I really need help with below it. All help is appreciated. :)
On Freenode, typing /NS ACC [user] will return whether or not the [user] is logged in with a numerical value, they decided 3 would be logged in. and 0-2 as some sort of not logged in.
So here is how the bot logs into my IRC channel... (feel free to join #tyreus on freenode, ask for BwaddArr (or his email))
<?php
set_time_limit(0); //Stop the script timing out
$server = "irc.freenode.net"; //server to connect to
$channel = "#tyreus"; //channel to connect to initialy
$password = "sumpass"; //password for bot to login to irc
$pass2 = "anotherpass"; //password to make the bot do stuff
$users[0] = "0"; //array of logged in users
$nickname = "Samcal"; //Set the bot's nick here
$logger = FALSE; //for the channel logger
$takeover = FALSE; //for the auto banner
$socket=fsockopen($server,'6667') ; //Connect and join the channel
stream_set_timeout($socket, 300); //Set a timeout value (so the bot quits if it's disconnected)
fwrite($socket, "NICK ".$nickname."\r\n");
fwrite($socket, "USER ".$nickname." 8 * ::\x01VERSON 1.0 Brad's bot\x01\n"); //read rfc 1459 to understand this line
while ($line=fgets($socket)) {
echo htmlentities($line)."<br>";
if (strpos($line, "433")>0) die("error nick in use"); //Quit if bot's nick is already taken (irc code 433 is received)
if (strpos($line, "004")>0) {
fwrite($socket, "JOIN ".$channel."\r\n"); //Join the channel if everything is ok (irc code 004 is received)
fwrite($socket, "NickServ IDENTIFY ".$nickname." ".$password."\r\n");
fwrite($socket, "ChanServ OP ".$channel." Samcal\r\n");
fwrite($socket, "MODE ".$channel." +v Samcal \r\n");
break;
}
}
And this is where i really need all the help! :)
if(strpos($line, "PRIVMSG ".$channel." :+oB\r\n")>0) { //Command to make the bot run the command
$name = "BwaddArr"; // my username, this can be easily changed to the other users who will need opping
$command = "NickServ ACC $name"; // the NickServ command I was talking about
$result = fwrite($socket, "$command \r\n"); // my attempt at retrieving the result
$accr = readline(strpos($line, "$result \r\n")); //part 2 of my failure to retrieve a result
$loggd = str_replace("3","three","$accr"); // replace '3' with 'three'
if($loggd != "three") { // if result is not three do below
fwrite($socket, "PRIVMSG ".$channel." :$name is not logged in. \r\n"); // write into the chat that the user is not logged in
}
if($loggd == "three") { // OP the user if they are logged in
fwrite($socket, "MODE ".$channel." +ov $name\r\n"); // sends the OPping command
}
}
?>
I assume the second snippet resides inside your while(fgets()) loop.
You won't have your result in the loop where you use fwrite() then. Either add another fgets() after
$result = fwrite($socket, "$command \r\n");
or consequently use your loop and maybe add a status flag to know how to treat the next execution of its body.
First of all, remove the password for your bot.(fixed)
Gave some tips on your IRC, good luck, you're on the right track now.
I did one, when I was young.
I used that kind of loop :
$irc = fsockopen($server, $port);
// ...
while(!feof($irc))
{
$line = fgets($irc, 2048);
// ...
// Parsing $line here
// ...
}
Hope this helps.
In your last code snippet you open your socket named $irc and write to a socket called $socket.
Either fix this or show us some more of your code where you use/introduce $socket.

Categories