how to accept multiple connection to the device - php

I am creating a socket script that will listen to our 3 devices.and the device is setup in one server ip and one port only.
$file = fopen('txt.log','a+');
$server = stream_socket_server('tcp://'.$ipserver.':'.$port, $errno, $errorMessage);
if(!$server) {
echo "$errorMessage ($errno)<br />\n";
}
else{
while($client = #stream_socket_accept($server,$timeout)) {
stream_copy_to_stream($client, $file);
fclose($file);
fclose($client);
}
}
but the problem is that if one device is connected,the two devices cannot connect anymore.I appreciate some one can help me how to get this work.or give me some idea
Thank you in advance.

$file = fopen('txt.log', 'a+');
$server = stream_socket_server("tcp://$ipserver:$port", $errno, $errorMessage);
if (!$server)
echo "$errorMessage ($errno)<br />\n";
else
{
$s = array($server);
$t = $timeout == -1 ? NULL : $timeout;
while ($r = $s and stream_select($r, $n=NULL, $n=NULL, $t))
foreach ($r as $stream)
if ($stream == $server) // new client
$s[] = stream_socket_accept($server, -1);
else
if (!fputs($file, fgets($stream)))
{
fclose($stream);
array_splice($s, array_search($stream, $s), 1);
}
}

Related

How to reject duplicate PHP socket connection from the same client?

I want to reject duplicate socket connection when the same connected client try to connect again.
The below code I tried to store gamerId into an array then later check the array if new gamerId already exist or not. But seems the duplicate connection already made but I don't want to make any duplicate connection.
$address = '127.0.0.5';
$port = 8085;
$sock = socket_create(AF_INET, SOCK_STREAM, 0) or die('Not Created');
$bind = socket_bind($sock, $address, $port) or die("Not Binded");
$listen = socket_listen($sock, 1) or die("Didnot listen");
$accept = socket_accept($sock) or die("Not Accepted");
$readData = trim(socket_read($accept, 1024));
$gamerId = array();
$errHandler = array();
$gamerIdlen = count($gamerId);
function checkDuplicate($gamerId, $gamerIdLen, $readData, $errHandler)
{
for ($i = 0; $i < $gamerIdLen; $i++) {
if ($gamerId[$i] === $readData) {
return 1;
}
}
}
if (checkDuplicate($gamerId, $gamerIdlen, $readData, $errHandler) == 1) {
array_push($errHandler, "exist");
} else if (checkDuplicate($gamerId, $gamerIdlen, $readData, $errHandler) != 1) {
array_push($gamerId, $readData);
}
do {
global $accept;
$accept = socket_accept($sock) or die("Not Accepted");
print_r($errHandler);
print_r($gamerId);
} while (true);
Keep a map of sockets to identities and close a (new) socket after identifying, when an identity is already in the map.
$map = [
[socket1] => User(123),
[socket1] => User(124),
];
<?php
$address = '127.0.0.5';
$port = 8085;
$server = socket_create(AF_INET, SOCK_STREAM, 0) or die('Not Created');
socket_bind($server, $address, $port) or die("Not Binded");
socket_listen($server, 10) or die("Did not listen");
// clients before checking gamerId
$pending = [];
// accepted clients
$clients = [];
// gamerId list
$gamerIds = [];
// gamerId for socket
$clientsIds = new WeakMap();
echo "Listening...\n";
do {
// wait for new client and new data on sockets
$read = [$server, ...$pending, ...$clients];
$write = null;
$error = null;
if(socket_select($read, $write, $error)){
foreach($read as $socket){
if($socket === $server){
// new connection
$pending[] = socket_accept($server);
printf("New Socket connected\n");
} else if(in_array($socket, $pending, true)) {
// data for pending connection
$readData = socket_read($accept, 1024);
// remove key from pending
if (($key = array_search($socket, $pending, true)) !== false) {
array_splice($pending, $key, 1);
}
// client disconnected already
if($readData === false){
printf("Pending client disconnected #%d\n", (int)$socket);
socket_close($socket);
unset($socket);
continue;
}
// here should be something to extract gamerId (e.g. make sure it is X characters)
$readData = trim($readData);
if(in_array($readData, $gamerIds, true)){
printf("Pending client already connected #%d, blocked...\n", (int)$socket);
// close connection
socket_close($socket);
unset($socket);
} else {
printf("Pending client accepted #%d\n", (int)$socket);
// accept client
$clients[] = $socket;
$gamerIds[] = $readData;
$clientsIds[$socket] = $readData;
}
} else {
// client communication
$readData = socket_read($accept, 1024);
if($readData === false){
printf("Client disconnected #%d\n", (int)$socket);
// remove client
if (($key = array_search($socket, $clients, true)) !== false) {
array_splice($clients, $key, 1);
}
// remove gamerId from the list
if(isset($clientsIds[$socket])){
if (($key = array_search($clientsIds[$socket], $gamerIds, true)) !== false) {
array_splice($gamerIds, $key, 1);
}
}
socket_close($socket);
unset($socket);
} else {
// handle data...
printf("Data received from socket #%d\n", (int)$socket);
}
}
}
}
} while (true);

Mailchimp Api Subscriber Check via php

I am trying to check if an e-mail address a user enters already is in the list of subscribers or not.
This is what I have tried so far:
<?php
$apikey = 'apikey';
$list_id = 'listid';
$chunk_size = 4096; //in bytes
$url = 'http://us14.api.mailchimp.com/export/1.0/list?apikey='.$apikey.'&id='.$list_id;
/** a more robust client can be built using fsockopen **/
$handle = #fopen($url,'r');
if (!$handle) {
echo "failed to access url\n";
} else {
$i = 0;
$header = array();
while (!feof($handle)) {
$buffer = fgets($handle, $chunk_size);
if (trim($buffer)!=''){
$obj = json_decode($buffer);
if ($i==0){
//store the header row
$header = $obj;
} else {
//echo, write to a file, queue a job, etc.
echo $obj[0];
}
$i++;
}
}
fclose($handle);
}
?>
This will return all email subscribers. I am trying to narrow it down to the specific e-mail the user entered, but I am stuck and don't know how to do it?
/** a more robust client can be built using fsockopen **/
$handle = #fopen($url,'r');
if (!$handle) {
echo "failed to access url\n";
} else {
$i = 0;
$header = array();
while (!feof($handle)) {
$buffer = fgets($handle, $chunk_size);
if (trim($buffer)!=''){
$obj = json_decode($buffer);
if ($i==0){
//store the header row
$header = $obj;
} else {
//echo, write to a file, queue a job, etc.
if ($obj[0] == "myemail#gmail.com") { echo "XXXXXXX";} else { }
}
$i++;
}
}
fclose($handle);
}
?>

socket_select() not a valid socket

I got this error:
Warning: socket_select(): supplied argument is not a valid Socket resource in /volume1/web/is/xxxx/listen-new.php on line 12
PHP Warning: socket_select(): supplied argument is not a valid Socket resource in /volume1/web/is/xxxx/listen-new.php on line 12
this my snippet code
My code is:
$port = $this->port;
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($sock, 0, $port);
socket_listen($sock);
$this->clients[] = $sock;
$data = array();
while (true) {
$read = $this->clients;
$write = array(); //NULL
$except = array();//NULL
$sckt = socket_select($read, $write, $except, 0);
if($sckt === false){
echo "socket_select() failed, reason: " .
socket_strerror(socket_last_error()) . "\n";
}
elseif($sckt > 0) {
if (in_array($sock, $read)) {
$this->clients[] = $newsock = socket_accept($sock);
//var_dump($this->gps);
socket_write($newsock, "Connected\n");
//var_dump($this->gps);
/**try{
socket_getpeername($newsock, $ip); //error
echo "New client connected: {$ip}\n";
}
catch(Exception $e){
echo "error : $e->getMessage()\n";
}**/
$key = array_search($sock, $read);
unset($read[$key]);
}
foreach ($read as $read_sock) {
$data = #socket_read($read_sock, 2048);
if ($data === false) {
$gpsdisc = array_search($read_sock, array_column($this->gps, 'pid'));
$key = array_search($read_sock, $this->clients);
unset($this->clients[$key]);
unset($this->gps[$gpsdisc]);
echo "client disconnected.\n";
continue;
}
else{
$data = trim($data);
if (!empty($data)) {
var_dump($data);
$buf = bin2hex($data);
$start = substr($buf, 0,4);
if($start=="7878"){
$protocol = substr($buf, 6,2);
if($protocol=="01"){
$imei = substr($buf, 8,16);
$cariGPS = $this->cariGPS($imei);
if($cariGPS!=NULL){
$this->setGPS($imei,$read_sock,$cariGPS);
$reply = $this->authLogin($data);
$rep = hex2bin("$reply");
socket_write($read_sock, $rep, strlen($rep));
}
else
echo "$imei salah";
}
elseif($protocol=="15"){
//echo "$buf\n";
$this->reply($data);
}
elseif($protocol=="12"){
$hex12 = bin2hex($data);
//echo "$hex12\n";
}
else{
$hex12 = bin2hex($data);
echo "$hex12\n";
}
echo "$protocol\n";
}
else{
if($data=="where"){
//echo $data."\n";
$this->where($this->gps);
}
elseif($data=="quit"){
$gpsdisc = array_search($read_sock, array_column($this->gps, 'pid'));
unset($this->gps[$gpsdisc]);
socket_close($read_sock);
$key = array_search($read_sock, $this->clients);
unset($this->clients[$key]);
}
else{
echo "command not found\n";
}
}
}
}
}
}
}
socket_close($sock);
PS I also had to change $write = null and $except = null
Are there any solution for this?
It looks like you supplied only the server code but omitted the client code. Can you post the client code please? I guess the problem is there. With my test client (fyi I used socket_create) I cannot reproduce the problem you are reporting.
Also mine is php7 (if you are curious).
This may have some hints for you: Socket_read() says "not a valid resource"

Minecraft Server: PHP echo $server->online_players

I have a problem with my website (http://www.zurfaria.ga/1/), where I'm trying to check how many players are online. I have downloaded this GitHub repository (https://github.com/mattvh/MCServerStatus) so I can query my server, but I can't seem to echo it in my HTML Here is my HTML and the PHP
<?php
require_once('/onlinecheck/Server.php')
require_once('/onlinecheck/Stats.php')
require_once('/onlinecheck/StatsException.php')
class MCServerStatus {
public $server;
public $online, $motd, $online_players, $max_players;
public $error = "OK";
function __construct($url, $port = '25565') {
$this->server = array(
"zurfaria.fmc.pw" => $url,
"25565" => $port
);
if ( $sock = #stream_socket_client('tcp://'.$url.':'.$port, $errno, $errstr, 1) ) {
$this->online = true;
fwrite($sock, "\xfe");
$h = fread($sock, 2048);
$h = str_replace("\x00", '', $h);
$h = substr($h, 2);
$data = explode("\xa7", $h);
unset($h);
fclose($sock);
if (sizeof($data) == 3) {
$this->motd = $data[0];
$this->online_players = (int) $data[1];
$this->max_players = (int) $data[2];
}
else {
$this->error = "Cannot retrieve server info.";
}
}
else {
$this->online = false;
$this->error = "Cannot connect to server.";
}
}
}
?>
<h1>Players Online:</h1>
<?php
echo $server->online_players; //Outputs the number of players online
?>
The HTML in between this code is fine, it works. What can I do to fix this? (I've looked up how to use the echo but didn't really understand it...)

How can I detect when a stream client is no longer available in PHP (eg network cable pulled out)

Is there any way (other than checking for ping responses) to detect when a client stream (I don't know if a stream would be any different from sockets) becomes unavailable (ie there is no longer any connection but no clean disconnection was made)?
Using this code:
#!/usr/bin/env php
<?php
$socket = stream_socket_server(
'tcp://192.168.1.1:47700',
$errno,
$errstr,
STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,
stream_context_create(
array(),
array()
)
);
if (!$socket) {
echo 'Could not listen on socket'."\n";
}
else {
$clients = array((int)$socket => $socket);
$last = time();
while(true) {
$read = $clients;
$write = null;
$ex = null;
stream_select(
$read,
$write,
$ex,
5
);
foreach ($read as $sock) {
if ($sock === $socket) {
echo 'Incoming on master...'."\n";
$client = stream_socket_accept(
$socket,
5
);
if ($client) {
stream_set_timeout($client, 1);
$clients[(int)$client] = $client;
}
}
else {
echo 'Incoming on client '.((int)$sock)."...\n";
$length = 1400;
$remaining = $length;
$buffer = '';
$metadata['unread_bytes'] = 0;
do {
if (feof($sock)) {
break;
}
$result = fread($sock, $length);
if ($result === false) {
break;
}
$buffer .= $result;
if (feof($sock)) {
break;
}
$continue = false;
if (strlen($result) == $length) {
$continue = true;
}
$metadata = stream_get_meta_data($sock);
if ($metadata && isset($metadata['unread_bytes']) && $metadata['unread_bytes']) {
$continue = true;
$length = $metadata['unread_bytes'];
}
} while ($continue);
if (strlen($buffer) === 0 || $buffer === false) {
echo 'Client disconnected...'."\n";
stream_socket_shutdown($sock, STREAM_SHUT_RDWR);
unset($clients[(int)$sock]);
}
else {
echo 'Received: '.$buffer."\n";
}
echo 'There are '.(count($clients) - 1).' clients'."\n";
}
}
if ($last < (time() - 5)) {
foreach ($clients as $id => $client) {
if ($client !== $socket) {
$text = 'Yippee!';
$ret = fwrite($client, $text);
if ($ret !== strlen($text)) {
echo 'There seemed to be an error sending to the client'."\n";
}
}
}
}
}
}
if ($socket) {
stream_socket_shutdown($socket, STREAM_SHUT_RDWR);
}
and a sockets client on a different computer, I can connect to the server, send and receive data, and disconnect cleanly and everything functions as expected. If, however, I pull the network connection on the client computer, nothing is detected on the server side - the server keeps on listening to the client socket, and also writes to it without any error manifesting itself.
As I understand it, calling feof($stream) will tell you if the remote socket disconnected, but I'm not absolutely certain about that. I'm using ping/pong myself while continuing to research a solution.
You need to set a socket timeout, in which case you get an error if a client does not respond in a timely fashion.
Check PHP's stream_set_timeout function:
http://www.php.net/manual/en/function.stream-set-timeout.php
Also check socket_set_option:
http://php.net/manual/en/function.socket-set-option.php
and finally, check out this great article on how to use sockets in PHP effectively:
"PHP Socket Programming, done the Right Way™"
http://christophh.net/2012/07/24/php-socket-programming/

Categories