How to check a UDP address exists with PHP and fsockopen? - php

I am using fsockopen to get information from a UDP address, the only problem being that some of the UDP addresses may not still be active.
I create the socket by
$fp = fsockopen($tracker, $port, $errno, $errstr, 1);
If the address is valid everything works fine, but if the address is invalid it generates this error
Warning: fsockopen(): php_network_getaddresses: getaddrinfo failed: Name or service not known in
I tried doing this but it still generates the error,
if(!$fp = fsockopen($tracker, $port, $errno, $errstr, 1)) {
// ERROR
} else {
// CONTINUE
}
I can error suppress it and all is good but I do not like error suppressing in my code.
How can I make sure any given UDP address is still active with php?
Thanks

Instead of suppressing the error # which you could do, you could implement your own error handler. set_error_handler
<?php
//Simple Blank error handler
set_error_handler('my_error_handler');
function my_error_handler($errno, $errstr, $errfile, $errline) {}
function checkUDP($host,$port=80){
//look no suppression
$fp = fsockopen("udp://".$host, $port, $errno, $errstr,1.0);
if (!$fp) {
return false;
} else {
fclose($fp);
return true;
}
}
$good = 'tracker.publicbt.com';
$bad = 'trjjacker.publicbt.com';
if(checkUDP($good)){
echo $good.' Good';
}else{
echo $good.' Bad';
}
echo '<br />';
if(checkUDP($bad)){
echo $bad.' Good';
}else{
echo $bad.' Bad';
}
//tracker.publicbt.com Good
//trjjacker.publicbt.com Bad
?>

Related

How to handle fsockopen error in PHP?

try {
$fp = fsockopen($site, $port, $errno, $errstr, 2);
}
catch(Exception $ex) {
echo 'error';
}
Why is the catch not working, while I'm see that warnings are given for fsockopen
Warning: fsockopen(): php_network_getaddresses: getaddrinfo failed: No such host is known.
and
Warning: fsockopen(): unable to connect to www.myrandsitedf.net:80 (php_network_getaddresses: getaddrinfo failed: No such host is known. )
I know that I can use # to suppress the error/warning messages, but I don't think that this is the right way to handle an error.
Also the Cronjob at my host doesn't allow PHP files with errors in it, # doesn't solve it.
You have to use the exception with global namespace.
Try this code:
try {
$fp = fsockopen($site, $port, $errno, $errstr, 2);
}
catch(\Exception $ex) { //used back-slash for global namespace
echo 'error';
}
This will work in php 5.3 or later.
Thanks.
You have to make the difference between exceptions and errors.
If you want errors (warning, etc...) to be transformed into exception such that they can be caught in the catch, you should register a error_handler that converts the error into an exception:
function error_handler($errno, $errstr, $errfile, $errline)
{
if( ($errno & error_reporting()) > 0 )
throw new ErrorException($errstr, 500, $errno, $errfile, $errline);
else
return false;
}
set_error_handler('error_handler');
The easy and proper way to do this
try {
$fp = #fsockopen($ip, $port, $errno, $errstr, 5);
#fclose($fp);
return true;
} catch (\Exception $th) {
// return "error";
return $th;
}

PHP escape error # for production

I want to escape the error generated by fsockopen and it works like this.
if ($fp = #fsockopen($host,$port,$errCode,$errStr,$waitTimeoutInSeconds)) { //... }
but i have been trying other things to avoid # and I have not managed.
Is there a code that I can use that is equivalent to this?
I have tried as well something like this just for testing purposes:
try{
if ($fp = fsockopen($host,$port,$errCode,$errStr,$waitTimeoutInSeconds)) {
/...
}
//..
} catch (Exception $e){
echo 'Error';
}
It does not work.
Warning: fsockopen(): unable to connect to localhost:79 (A connection
attempt failed because the connected party did not properly respond after a period of time or established
connection failed because connected host has failed to respond.
Use set_error_handler() an convert all the errors to an exception you can catch afterwards:
set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
if(0 === error_reporting())
return false;
throw new PHPException($errno, $errstr, $errfile, $errline, $errcontext);
});
So now you can catch the PHP error:
try {
if ($fp = fsockopen($host,$port,$errCode,$errStr,$waitTimeoutInSeconds)) {
//...
}
//..
} catch (\Exception $e){
echo 'Connection failed: ' , $e->getMessage();
}
echo 'Don\'t worry... go on!';
You can disable notices and warnings in production systems (instead write to a log):
error_reporting(E_ERROR);
In development environments you'd probably want all errors, notices and warnings on though:
error_reporting(E_ALL);
check out the error reporting levels here: http://php.net/manual/en/errorfunc.configuration.php#ini.error-reporting
EDIT: To check for an error:
$fp = #fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
...
}
I think if you are handling failure scenarios then consciously suppressing a warning using # is ok.

Checking UDP port in PHP

I'm trying to check a servers UDP port using PHP. here is my code:
<?php
set_error_handler('my_error_handler');
function my_error_handler($errno, $errstr, $errfile, $errline) {}
function checkUDP($host,$port=80){
$fp = fsockopen("udp://".$host, $port, $errno, $errstr,1.0);
if (!$fp) {
return false;
} else {
fclose($fp);
return true;
}
}
if(checkUDP($MyIP,9)){
echo $MyIP.' is open';
}else{
echo $MyIP.' is closed';
}
echo '<br />';
?>
But I always get True result (port is open). This code works on TCP port but why I couldn't get the UDP port results?

Checking service fsockopen()

I'm trying to check service on port 9998. To do so I'm using fsockopen() function.
Like this:
$host = "1.1.1.1";
$port = "9998";
$checkconn = fsockopen($host, $port, $errno, $errstr, 1);
if($checkconn >= 1){
echo 'ok';
} else {
echo "$errstr";
}
It always returns "Connection Timed Out - 110", but the port is open and there is service running there.
If I change the port (like 80), it returns successful, but why not on the 9998 port?
A 1 second connect timeout is not very long. Network lag can be enough to trigger that even when the host/port is valid. I would suggest using at least 2.5 - 5 seconds instead.
Also, you should be checking the result of fsockopen() for FALSE instead of < 1 to know when it fails.
Try this:
$host = "1.1.1.1";
$port = "9998";
$checkconn = fsockopen($host, $port, $errno, $errstr, 5);
if(!$checkconn){
echo "($errno) $errstr";
} else {
echo 'ok';
}

Trouble getting PHP fsockopen to ignore errors

I'm setting up reporting on my PHP script with etsy's open source statsd library.
I'm basing my connection on their given example, but I'm running into an issue where it seems like fsockopen is ignoring try/catch and is printing its errors.
Everything works grand when the statsd server is up and running - but if it's down or the php script cannot connect to it:
Warning: fsockopen(): php_network_getaddresses: getaddrinfo failed:
Name or service not known
I even attempted adding # in front of fsockopen, but no dice. It also seems to be completely ignoring the timeout setting, as it takes about 20 seconds to return the error:
try {
$host = 'stats.thisserverisdown.com';
$port = '8125';
if ( $fp = #fsockopen("udp://$host", $port, $errno, $errstr, 1) ) {
if (!(get_resource_type($fp) == 'stream')) { return false; }
stream_set_timeout($fp,1);
stream_set_blocking($fp,false);
foreach ($sampledData as $stat => $value) {
#fwrite($fp, "$stat:$value");
}
#fclose($fp);
}
return true;
} catch (Exception $e) {
return false;
}
fsockopen is not throwing the error. Because fsockopen has to resolve the hostname you provided, it calls getaddinfo(), which is failing.
Try supplying an IP address, or:
fsockopen( #"udp://$host", ...

Categories