How to send binary data representing 01 (PHP)?
My Server code (sockets TCP, address is only example. I use my server address of course)
error_reporting(E_ALL);
set_time_limit(0);
ignore_user_abort(true);
$address = '11.111.111.111'; // example server address
$port = 9000; // example port
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($sock, $address, $port);
socket_listen($sock);
$clients = array($sock);
while(true) {
$read = $clients;
if (socket_select($read, $write = NULL, $except = NULL, 0) < 1) {
continue;
}
if (in_array($sock, $read)) {
$clients[] = $newsock = socket_accept($sock);
$key = array_search($sock, $read);
unset($read[$key]);
}
foreach ($read as $read_sock) {
$data = #socket_read($read_sock, 1024);
if ($data === false) {
// remove client for $clients array
$key = array_search($read_sock, $clients);
unset($clients[$key]);
echo "client disconnected.\n";
// continue to the next client to read from, if any
continue;
}
$data = trim($data);
// check if there is any data after trimming off the spaces
if (!empty($data)) {
// send this to all the clients in the $clients array (except the first one, which is a listening socket)
foreach ($clients as $send_sock) {
// if its the listening sock or the client that we got the message from, go to the next one in the list
if ($send_sock == $sock || $send_sock == $read_sock) {
continue;
}
$fp = fopen('socket_communication.txt', 'a');
fwrite($fp, date("Y-m-d H:i:s")." - DATA ".$data."\n");
fclose($fp);
$value = unpack('H*', "1");
$response = base_convert($value[1], 16, 2);
socket_write($send_sock, $response, 1);
} // end of broadcast foreach
}
}
}
echo "Closing sockets...";
socket_close($sock);
I would like to server sent binary data (01 or 1).
I use unpack function and convert it by base_convert but it doesnt works.
This code send response to client
$value = unpack('H*', "1");
$response = base_convert($value[1], 16, 2);
socket_write($send_sock, $response, 1);
Related
I've written a pair of PHP socket servers that listen around for commands and respond to them. The problem is that they do so by listening in an infinite loop, and thus are eating up CPU.
So how do I do this (1) without eating up CPU; and (2) without slowing down the socket commands, particularly if I have several come in in sequence?
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($sock, $address, $port);
socket_listen($sock);
$clients = array($sock);
$write = NULL;
$except = NULL;
while (true) {
$read = $clients;
if (socket_select($read, $write, $except, 0) < 1)
continue;
if (in_array($sock, $read)) {
$clients[] = socket_accept($sock);
$key = array_search($sock, $read);
unset($read[$key]);
}
foreach ($read as $read_sock) {
/* I tried putting a tiny sleep here, but if I run several socket connections for the same user sequentially, they see a notable slowdown */
$data = #socket_read($read_sock, 1024, PHP_NORMAL_READ);
if ($data === false) {
$key = array_search($read_sock, $clients);
unset($clients[$key]);
echo "client disconnected.\n";
continue;
}
$data = trim($data);
/* And this is the heart of my loop */
}
} // end of reading foreach
}
// close the listening socket
socket_close($sock);
i have implemented a socket server in localhost
script i used is from http://www.sanwebe.com/2013/05/chat-using-websocket-php-socket
script is
$host = "localhost"; //host
$port = 9099; //port
if(isset($argv[1]))
{
$host = $argv[1];
}
if(isset($argv[2]))
{
$port = $argv[2];
}
$null = NULL; //null var
$ips=array();
//Create TCP/IP sream socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//reuseable port
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
//bind socket to specified host
socket_bind($socket, 0, $port);
//listen to port
socket_listen($socket);
//create & add listning socket to the list
$clients = array($socket);
$clients_ip=array();
//start endless loop, so that our script doesn't stop
while (true) {
//manage multipal connections
$changed = $clients;
//returns the socket resources in $changed array
socket_select($changed, $null, $null, 0, 10);
//check for new socket
if (in_array($socket, $changed)) {
$socket_new = socket_accept($socket); //accpet new socket
socket_getpeername($socket_new, $ip);
$clients[] = $socket_new; //add socket to client array
$clients_ip[$ip] = $socket_new;
$header = socket_read($socket_new, 1024); //read data sent by the socket
perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake
//get ip address of connected socket
$ips[]=$ip;
$response = mask(json_encode(array('ip'=>$ip,'type'=>'c', 'message'=>$ip.' connected','ips'=>$ips))); //prepare json data
send_message($response); //notify all users about new connection
//make room for new socket
$found_socket = array_search($socket, $changed);
unset($changed[$found_socket]);
}
//print_r($changed);exit;
if(count($changed)>0)
{
//loop through all connected sockets
foreach ($changed as $changed_socket) {
//check for any incomming data
while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)
{
$received_text = unmask($buf); //unmask data
$tst_msg = json_decode($received_text); //json decode
//$user_name = $tst_msg->name; //sender name
//$user_message = $tst_msg->message; //message text
//$user_color = $tst_msg->color; //color
//prepare data to be sent to clientjson_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message, 'color'=>$user_color))
$response_text = mask($received_text);
if(isset($tst_msg->type))
{
if($tst_msg->type=="n")
{
#socket_write($clients_ip[$tst_msg->to_ip],$response_text,strlen($response_text));
}
}
//send_message($response_text); //send data
break 2; //exist this loop
}
$buf = #socket_read($changed_socket, 1024, PHP_NORMAL_READ);
if ($buf === false) { // check disconnected client
// remove client for $clients array
$found_socket = array_search($changed_socket, $clients);
socket_getpeername($changed_socket, $ip);
unset($clients[$found_socket]);
if (($key = array_search($ip, $ips)) !== false)
{
unset($ips[$key]);
}
$ips=array_values($ips);
//notify all users about disconnected connection
$response = mask(json_encode(array('ip'=>$ip,'type'=>'d', 'message'=>$ip.' disconnected','ips'=>$ips)));
send_message($response);
}
}
}
}
// close the listening socket
socket_close($sock);
function send_message($msg)
{
global $clients;
foreach($clients as $changed_socket)
{
#socket_write($changed_socket,$msg,strlen($msg));
}
return true;
}
//Unmask incoming framed message
function unmask($text) {
$length = ord($text[1]) & 127;
if($length == 126) {
$masks = substr($text, 4, 4);
$data = substr($text, 8);
}
elseif($length == 127) {
$masks = substr($text, 10, 4);
$data = substr($text, 14);
}
else {
$masks = substr($text, 2, 4);
$data = substr($text, 6);
}
$text = "";
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i] ^ $masks[$i%4];
}
return $text;
}
//Encode message for transfer to client.
function mask($text)
{
$b1 = 0x80 | (0x1 & 0x0f);
$length = strlen($text);
if($length <= 125)
$header = pack('CC', $b1, $length);
elseif($length > 125 && $length < 65536)
$header = pack('CCn', $b1, 126, $length);
elseif($length >= 65536)
$header = pack('CCNN', $b1, 127, $length);
return $header.$text;
}
//handshake new client.
function perform_handshaking($receved_header,$client_conn, $host, $port)
{
$headers = array();
$lines = preg_split("/\r\n/", $receved_header);
foreach($lines as $line)
{
$line = chop($line);
if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))
{
$headers[$matches[1]] = $matches[2];
}
}
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
//hand shaking header
$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"WebSocket-Origin: $host\r\n" .
"WebSocket-Location: ws://$host:$port/demo/shout.php\r\n".
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
socket_write($client_conn,$upgrade,strlen($upgrade));
}
i run this program in xampp shell like
php -q path-to-server\server.php
i have a server with shell support
But when i run script
php -q path-to-server\server.php
it works but when shell is closed server will close automatically
so how to run this server continuously with out automatically closing?
i have a linux hosting package
Use this code,
php -f server.php
if you want to run continusely in banground you can use nohub
nohup php server.php &
if want to kill the process you use kill
kill processid
you can run in terminal
php filename.php
I'm guessing you are connecting to the server by ssh?
The server session is ending and all open proccesses are killed that is why your server instance is ending, you are running it from a non-privileged user.
So the way I use is to install screen on the remote server and use that.
https://www.gnu.org/software/screen/manual/screen.html
Or it looks like you might be running a windows server. If this is the case I would recomend using a Linux server as windows makes this a little harder. You will have to run your server instance as a system proccess.
you should run this command as a background proccess like
nohup php -f myBind.php > /dev/null &
Also you can put a simple sccript to crontab for checking your bind.php is up or not if its not run it again.
I'm trying to extract song title from live mp3 streams using SC protocol. The php script works fine with some IPs and ports, however with some IPs and ports I cannot get required headers from the response to determine the meta-block frequency, therefore I cannot find the location of the song title in the stream. Here's my code:
<?php
while(true)
{
//close warning messages (re-open for debugging)
error_reporting(E_ERROR | E_PARSE);
//create and connect socket with the parameters entered by the user
$sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
echo "Establishing connection to the given adress...\n";
$fp = fsockopen($argv[1], $argv[2], $errno, $errstr, 10);
if($fp)
{
echo "Connection established.\n";
$result = socket_connect($sock, $argv[1], $argv[2]);
//prepare request
$request = "GET / HTTP/1.1\r\n";
$request .= "Icy-MetaData: 1\r\n\r\n";
//send request
socket_write($sock,$request,strlen($request));
//set sentinel boolean value's initial value
$headers = true;
//put the segment to be parsed into a string variable
$l = socket_read($sock,2048);
$meta = "";
$streamurl = "";
$checkContentType = false;
//Parsing metadata frequency and streamurl from response's headers.
foreach(preg_split("/((\r?\n)|(\r\n?))/", $l) as $line)
{
if(!(strpos($line, "metaint:") === false))
{
$meta = $line;
}
if(!(strpos($line, "icy-url:") === false))
{
$streamurl = $line;
}
if(!strpos($line, "audio/mpeg") === false)
{
$checkContentType = true;
}
}
echo $l;
//Checking if the content of the stream is mpeg or not
if($checkContentType)
{
$pos = strpos($meta, ":");
$interval = intval(substr($meta,$pos+1));
$pos = strpos($streamurl, ":");
$streamurl = substr($streamurl, $pos+1);
$flag = false;
//initialize bytecount to 0
$bytecount = 0;
//Extracting song title using SC protocol
while($headers)
{
$l = socket_read($sock,PHP_NORMAL_READ);
$bytecount++;
if($bytecount == $interval )
{
$headers = false;
$flag = true;
}
if($flag)
{
$len = ord($l);
}
}
//Determining length variable
$len = $len * 16;
$string = socket_read($sock,$len);
$pos2 = strpos($string, "'") + 1;
$pos3 = strpos($string, ";",$pos2) -1;
$songtitle = substr($string, $pos2, ($pos3-$pos2));
//Formatting the log entry
$finalstr = "[".date("c")."]"."[".$streamurl."]".$songtitle."\n";
echo "logged".$finalstr;
//finalize connection
socket_close($sock);
//Writing the requested info to a log file
file_put_contents("log.txt", $finalstr,FILE_APPEND | LOCK_EX);
//waiting 5 minutes
echo "Logging next entry in five minutes. \n";
sleep(300);
}
else
{
echo "Content of the stream is not suitable.\n";
exit;
}
}
else
{
echo "Unable to connect to the given ip and port.\n Exiting...\n";
socket_close($sock);
exit;
}
}
?>
I've never tried to access shoutcast programatically but I've run streaming audio servers in the past. There are actually two different flavours of shoutcast server and I would guess your program is trying to talk to one and these broken servers are the other type.
From the post READING SHOUTCAST METADATA FROM A STREAM:
Turns out that SHOUTcast and Icecast (two of the most popular server
applications for streaming radio) are supposed to be compatible, but
the response message from each server is slightly different.
Full details about the shoutcast protocol: Shoutcast Metadata Protocol
i'm trying write asynchronous socket listener code in php. but listener response answer only for first request and for other requests it only can receive packets without response (i'm checking with sniffer) also i'm counting how many time loop was active and loop is active only for first request ...... i'll show my Code :
addr = '192.168.0.117';
$port = 7878;
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
socket_bind($sock, $addr, $port) or die('Could not bind to address');
socket_listen($sock);
$null = NULL;
$clients = Array();
$cc = 0; // loop counter
while(true){
echo $cc."<br>";
$cc = $cc +1;
$read[0] = $sock;
$ready = socket_select($read,$null,$null,$null);
$client = socket_accept($sock);
$input = socket_read($client, 312);
echo $input;
if($input == "exit"){
socket_close($client);
socket_close($sock);
return false;
}
$output = 0x11;
socket_write($client,$output);
$input = "";
}
May be you are closing the listening socket right after the first client sends exit command. You should close only client socket when the client sends exit command. And you return false from the while loop. This means obviously it will process only one client.
if($input == "exit"){
socket_close($client);
socket_close($sock); // Think about this Line.
return false; // Think about this Line.
}
I have a gps simulator, which sends continuous location data (nmea strings) through tcpip to 192.168.0.178:2323. How do I get that data using tcp socket and write to DB (php & mysql)?
Thanks!
This is a loaded question. First you need to read the data. Then you have to put some structure to the data for it to be usable. It doesn't do you much good to just dump lat-lon to a database. You probably want to save it as a waypoint or part of a track etc.
So I have no answer to the DB question. Here is part of the PHP program I use to read GPS data off my phone connected to a CradlePoint router. It's modified from GoogleNav code.
function read_gps() {
set_time_limit(5);
$fp = fsockopen ("192.168.0.1", 8080, $errno, $errstr, 30);
if (!$fp) {
die ("$errstr ($errno)");
}
$point=false;
$status="";
$fix=0;
while (!$point) {
$string=#fgets($fp, 4096);
switch (substr($string,0,6)) {
case "\$GPRMC" :
list($sentence, $time, $status, $latitude, $NS, $longitude, $EW, $speed, $course, $date, $magvar, $magvarEW)= explode(",", trim($string));
$latd=convdec($latitude, $NS);
$lond=convdec($longitude, $EW);
break;
case "\$GPGGA" :
list($sentence, $time, $latitude, $NS, $longitude, $EW, $fix, $nbsat, $HDOP, $altitude,,,,,)= explode(",", trim($string));
$latd=convdec($latitude, $NS);
$lond=convdec($longitude, $EW);
break;
default :
break;
}
if ($status=="A" and $fix == 1){
$point=true;
}
}
...
?>
Start here: PHP Sockets
One of the user comments gives a helpful sample implementation of a TFTP client
<?php
function tftp_fetch($host, $filename)
{
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
// create the request packet
$packet = chr(0) . chr(1) . $filename . chr(0) . 'octet' . chr(0);
// UDP is connectionless, so we just send on it.
socket_sendto($socket, $packet, strlen($packet), 0x100, $host, 69);
$buffer = '';
$port = '';
$ret = '';
do
{
// $buffer and $port both come back with information for the ack
// 516 = 4 bytes for the header + 512 bytes of data
socket_recvfrom($socket, $buffer, 516, 0, $host, $port);
// add the block number from the data packet to the ack packet
$packet = chr(0) . chr(4) . substr($buffer, 2, 2);
// send ack
socket_sendto($socket, $packet, strlen($packet), 0, $host, $port);
// append the data to the return variable
// for large files this function should take a file handle as an arg
$ret .= substr($buffer, 4);
}
while(strlen($buffer) == 516); // the first non-full packet is the last.
return $ret;
}
?>