continuously loading if there is no internet connection - php

I am currently developing a Online Controlled home but I have a problem with the internet connection checker.
I have this code to detect whether there is an internet connection or there is no internet connection.
$check = #fsockopen("www.google.com", 80);
if($check){
return true;
fclose($check);
}else{
return false;
fclose($check);
}
but the problem is, when my Raspberry Pi don't have an internet connection then it continuously load the page forever.
the full script is here
<?php
function checkConnection(){
$check = #fsockopen("www.google.com", 80);
if($check){
return true;
fclose($check);
}else{
return false;
fclose($check);
}
}
if(checkConnection()==true){
echo '[{"status":"success","result":"Internet Connection is Available"}]';
}else{
echo '[{"status":"fail","result":"No Internet Connection"}]';
}
?>

fsockopen takes a timeout as the last param, which only applies while connection the socket
DNS lookup can be a factor too, AFAIK you can't control the timeout for that, unless if you're going to use gethostbyname() in that case you can use
putenv('RES_OPTIONS=retrans:1 retry:1 timeout:1 attempts:1');
to limit DNS lookup to 1s.
Based on your code here's how i would implement it.
function is_connected()
{
//1. provide a timeout to your socket
//2. use example.com as a domain, that's what it's made for (testing)
$socket = #fsockopen("www.example.com", 80, $err_no, $err_str, 5);
if ($socket){
fclose($socket);
return true;
}
return false;
}
$success = json_encode(["status" => "success","result" => "Internet is Available"]);
$failure = json_encode(["status" => "fail","result" => "Internet is Unavailable"]);
echo is_connected() ? $success : $failure;

Perhaps a small change in your function might enlighten the situation. For example:
function checkConnection() {
$fp = #fsockopen("www.google.com", 80, $errno, $errstr, 3);
if (!$fp) {
return "$errstr ($errno)<br />\n";
} else {
return true;
}
}
$con = checkConnection();
if ($con===true) {
echo json_encode( ["status" => "success","result" => "Internet Connection is Available"] );
} else {
// should not be - No Internet Connection is Available
echo json_encode( ["status" => "fail","result" => $con] );
}
PS: Try it out in PHPFiddle and make sure to change the port from 80 to 83 for example. This of course does not mean that you don't have internet connection but that the host you reach at the specified port does not reply. Anyway it will simply fail the function and return the error message. Also please do notice the timeout limit of 3 seconds in fsocopen since you may alter it accordingly to your needs.
EDIT
A simpler and perhaps more accurate approach on what you are trying to do could be this.
function checkConnection($hostname) {
$fp = gethostbyname($hostname);
if (!inet_pton($fp)) {
return json_encode( ["status" => "fail","result" => "Internet Connection is not Available or Host {$hostname} is wrong or does not exist."] );
} else {
return json_encode( ["status" => "success","result" => "Internet Connection is Available. Host {$hostname} exists and resolves to {$fp}"] );
}
}
echo checkConnection('www.google.com');
You might want to check this comment in php.net on setting alternative options for gethostbyname.

Related

PHP file_get_contents check source online or not before do the execution

I'm using PHP file_get_contents to read text file data.
Assuming I have 2 IP Address, 1 online and 1 offline:
192.168.180.181 - Online
192.168.180.182 - Offline
And the PHP
$fileAccept = file_get_contents("\\\\192.168.180.181\\Reports\\".$dModel['MODEL_NAME'].$source."\\Accept\\Accept_".$dDtl['MODEL_CODE']."_".$dateCode."_".$dDtl['TS_CODE'].".txt");
As We Know IP Address 192.168.180.182 is offline, then I tried to run the code. And result the page always loading.
My question, how can I prevent it maybe first need to check the IP is alive or not, if alive then can continue to next step.
Maybe something like this:
if(IP IS OFFLINE)
{
echo "do not do anything";
}
else
{
echo "do something";
}
you can try something like that
$scc = stream_context_create(array('http'=>
array(
'timeout' => 120, //120 seconds
)
));
$url = "http://192.168.180.181/....";
$handle = file_get_contents('$url, false, $scc);
you can create two handles and check whether is ok with if statement, of course you can change the timeout to suites you
Update:
if accessing file locally you can check this stream_set_timeout() function , the documentation is here
This solution is based on pinging the IP you need to check
class IPChecker{
public static function isIPOnline($ip){
switch (SELF::currentOS()){
case "windows":
$arg = "n";
break;
case "linux":
$arg = "c";
break;
default: throw new \Exception('unknown OS');
}
$result = "";
$output = [];
// to debug errors add 2>&1 to the command to fill $output
// https://stackoverflow.com/questions/16665041/php-why-isnt-exec-returning-output
exec("ping -$arg 2 $ip " , $output, $result);
// if 0 then the there is no errors like "Destination Host Unreachable"
if ($result === 0) return true;
return false;
}
public static function currentOS(){
if(strpos(strtolower(PHP_OS), "win") !== false) return 'windows';
elseif (strpos(strtolower(PHP_OS), "linux") !== false) return 'linux';
//TODO: extend other OSs here
else return 'unknown';
}
}
usage example
var_dump( IPChecker::isIPOnline("192.168.180.181") );// should outputs bool(true)
var_dump( IPChecker::isIPOnline("192.168.180.182") );// should outputs bool(false)
I have used these answers (1, 2) in my answer

php - check internet connect and DNS resolution

I know this may have been asked before, but I can't find anything that quite matches my specific requirements.
I'm loading a page on a local Linux server, when it loads I need to know does the server it is running on have Internet Access and is DNS resolving.
I've got this working, BUT... if there is no Internet connection the page takes a very long time to load, if there is a connection then it loads instantly.
I'm using the following to check for Internet Access:
$check1 = checkState('google-public-dns-a.google.com',53);
$check2 = checkState('resolver1.opendns.com',53);
if ($check1 == "YES" || $check2 == "YES"){
echo "Internet Available";
}
function checkState($site, $port) {
$state = array("NO", "YES");
$fp = #fsockopen($site, $port, $errno, $errstr, 2);
if (!$fp) {
return $state[0];
} else {
return $state[1];
}
}
and checking DNS resolution using:
$nameToIP = gethostbyname('www.google.com');
if (preg_match('/^\d/', $nameToIP) === 1) {
echo "DNS Resolves";
}
Can anyone recommend a better way ? so if there is no connection the page doesn't stall for a long time.
Thanks
You can use fsockopen
Following example works well and tells you whether you are connected to internet or not
function is_connected() {
$connected = #fsockopen("www.google.com", 80); //website, port (try 80 or 443)
if ($connected){
fclose($connected);
return true;
}
return false;
}
Reference : https://stackoverflow.com/a/4860432/2975952
Check DNS resolves here
function is_site_alive(){
$response = null;
system("ping -c 1 google.com", $response);
if($response == 0){
return true;
}
return false;
}
Reference : https://stackoverflow.com/a/4860429/2975952

PHP Packet Sending with defined socket

I am wanting to send a packet to a server using PHP. I am trying to figure out how to conect with a predetermined IP, port and socket id. However, my code does not seem to be working properly, although no error is being shown.
function SendData($data){
$ip = "1.1.1.1";
$port = 31000;
$my_sock = '525'
$sock = fsockopen($ip, $port, $errnum, $errstr, $timeout);
if(!is_resource($sock)){
return false;
} else {
fputs($sock, $data);
return true;
}
SendData("#E");
SendData("DJ");
fclose($sock);
}
I am also considering doing this in Javascript, if possible. Whichever way works best.
Doesn't your SendData function go into infinite recursion? Something like:
SendData('X')
fsockopen(...)
SendData('#E')
fsockopen(...)
SendData('#E')
fsockopen(...)
SendData('#E')
...

PHP checking if server is alive

I need to check if a group of servers, routers and switches is alive. I have been searching for something reliable that would work with IPs and ports for over an hour now, could anyone help?
Ended up using
function ping($addr, $port='') {
if(empty($port)) {
ob_start();
system('ping -c1 -w1 '.$addr, $return);
ob_end_clean();
if($return == 0) {
return true;
} else {
return false;
}
} else {
$fp = fsockopen("udp://{$addr}", $port, $errno, $errstr);
if (!$fp) {
return false;
} else {
return true;
}
}
}
Servers, routers and switches...the one commonality that all of them share is the ability to accept SNMP requests if an SNMP service is running. Sounds like what you are trying to do is implement a funny workaround to a monitoring system (nagios, etc....)
As per: http://php.net/manual/en/book.snmp.php
<?php
$endpoints = array('10.0.0.1','10.0.0.2','10.0.0.3','10.0.0.4','10.0.0.5');
foreach ($endpoints as $endpoint) {
$session = new SNMP(SNMP::VERSION_2c, $endpoint, 'boguscommunity');
var_dump($session->getError());
// do something with the $session->getError() if it exists else, endpoint is up
}
?>
This will tell you if the endpoint is alive and the SNMP service is running. Specific to seeing if the port is available / open, you can use fsockopen():
http://php.net/manual/en/function.fsockopen.php
<?php
$fp = fsockopen("udp://127.0.0.1", 13, $errno, $errstr);
if (!$fp) {
echo "ERROR: $errno - $errstr<br />\n";
}
?>
$ip = "123.456.789.0";
$ping = exec("ping -c 1 -s 64 -t 64 ".$ip);
var_dump($ping);
// and so forth.
if you are checking for mysql you can use something like
if (mysqli_ping($ip)) echo "sweet!";
else echo "oh dam";
I would be a little concerned using the ping option as that can be blocked, and out of no where ...

Determine in php script if connected to internet?

How can I check if I'm connected to the internet from my PHP script which is running on my dev machine?
I run the script to download a set of files (which may or may not exist) using wget. If I try the download without being connected, wget proceeds to the next one thinking the file is not present.
<?php
function is_connected()
{
$connected = #fsockopen("www.example.com", 80);
//website, port (try 80 or 443)
if ($connected){
$is_conn = true; //action when connected
fclose($connected);
}else{
$is_conn = false; //action in connection failure
}
return $is_conn;
}
?>
You can always ping good 'ol trusty google:
$response = null;
system("ping -c 1 google.com", $response);
if($response == 0)
{
// this means you are connected
}
This code was failing in laravel 4.2 php framework with an internal server 500 error:
<?php
function is_connected()
{
$connected = #fsockopen("www.some_domain.com", 80);
//website, port (try 80 or 443)
if ($connected){
$is_conn = true; //action when connected
fclose($connected);
}else{
$is_conn = false; //action in connection failure
}
return $is_conn;
}
?>
Which I didn't want to stress myself to figure that out, hence I tried this code and it worked for me:
function is_connected()
{
$connected = fopen("http://www.google.com:80/","r");
if($connected)
{
return true;
} else {
return false;
}
}
Please note that: This is based upon the assumption that the connection to google.com is less prone to failure.
The accepted answer did not work for me. When the internet was disconnected it threw a php error. So I used it with a little modification which is below:
if(!$sock = #fsockopen('www.google.com', 80))
{
echo 'Not Connected';
}
else
{
echo 'Connected';
}
Why don't you fetch the return code from wget to determine whether or not the download was successful? The list of possible values can be found at wget exit status.
On the other hand, you could use php's curl functions as well, then you can do all error tracking from within PHP.
There are various factors that determine internet connection. The interface state, for example. But, regardles of those, due to the nature of the net, proper configuration does not meen you have a working connection.
So the best way is to try to download a file that you’re certain that exists. If you succeed, you may follow to next steps. If not, retry once and then fail.
Try to pick one at the destination host. If it’s not possible, choose some major website like google or yahoo.
Finally, just try checking the error code returned by wget. I bet those are different for 404-s and timeouts. You can use third parameter in exec call:
string exec ( string $command [, array &$output [, int &$return_var ]] )
/*
* Usage: is_connected('www.google.com')
*/
function is_connected($addr)
{
if (!$socket = #fsockopen($addr, 80, $num, $error, 5)) {
echo "OFF";
} else {
echo "ON";
}
}
Also note that fopen and fsockopen are different. fsockopen opens a socket depending on the protocol prefix. fopen opens a file or something else e.g file over HTTP, or a stream filter or something etc. Ultimately this affects the execution time.
You could ping to a popular site or to the site you're wgetting from (like www.google.nl) then parse the result to see if you can connect to it.
<?php
$ip = '127.0.0.1'; //some ip
exec("ping -n 4 $ip 2>&1", $output, $retval);
if ($retval != 0) {
echo "no!";
}
else
{
echo "yes!"; }
?>
Just check the result of wget. A status code of 4 indicates a network problem, a status code of 8 indicates a server error (such as a 404). This only works if you call wget for each file in sequence, rather than once for all the files.
You can also use libcurl with PHP, instead of calling wget. Something like:
foreach (...) {
$c = curl_init($url);
$f = fopen($filepath, "w")
curl_setopt($c, CURLOPT_FILE, $f);
curl_setopt($c, CURLOPT_HEADER, 0);
if (curl_exec($c)) {
if (curl_getinfo($c, CURLINFO_HTTP_CODE) == 200) {
// success
} else {
// 404 or something, delete file
unlink($filepath);
}
} else {
// network error or server down
break; // abort
}
curl_close($c);
}
This function handles what you need
function isConnected()
{
// use 80 for http or 443 for https protocol
$connected = #fsockopen("www.example.com", 80);
if ($connected){
fclose($connected);
return true;
}
return false;
}
You can use this by adding this inside a class:
private $api_domain = 'google.com';
private function serverAliveOrNot()
{
if($pf = #fsockopen($this->api_domain, 443)) {
fclose($pf);
$_SESSION['serverAliveOrNot'] = true;
return true;
} else {
$_SESSION['serverAliveOrNot'] = false;
return false;
}
}
+1 on Alfred's answer, but I think this is an improved version:
function hasInternet()
{
$hosts = ['1.1.1.1', '1.0.0.1', '8.8.8.8', '8.8.4.4'];
foreach ($hosts as $host) {
if ($connected = #fsockopen($host, 443)) {
fclose($connected);
return true;
}
}
return false;
}
My reasons:
This pings more than 1 server and will only fail if all 4 fails
If first host works, it will return true immediately
IP addresses are from CloudFlare and Google DNS which basically controls most of the internet and always online
1.1.1.1 is rated the fastest DNS resolver (Source)
Only doubt I have is to use port 443 or 80? Suggestions would be appreciated! :)
Very PHP way of doing it is
<?php
switch (connection_status())
{
case CONNECTION_NORMAL:
$txt = 'Connection is in a normal state';
break;
case CONNECTION_ABORTED:
$txt = 'Connection aborted';
break;
case CONNECTION_TIMEOUT:
$txt = 'Connection timed out';
break;
case (CONNECTION_ABORTED & CONNECTION_TIMEOUT):
$txt = 'Connection aborted and timed out';
break;
default:
$txt = 'Unknown';
break;
}
echo $txt;
?>
https://www.w3schools.com/php/func_misc_connection_status.asp

Categories