How to identify whether server's port is accessible? - php

I am trying to implement a PHP script that will ping an IP on a specific port and echo out whether the server is online / offline. This way, users will be able to see if non-access to the server is a server fault or a own network problem.
The site is currently on http://Dev.stevehamber.com. You can see the "Online" is wrapped in a class of 'PHP' and I need this to reflect if the server is online or offline. The application runs on port TCP=25565 so I need the output to show if this port is reachable or not.
Here is a snippet I found that is (I suppose) what I'm looking for:
<?php
$host = 'www.example.com';
$up = ping($host);
// if site is up, send them to the site.
if( $up ) {
header('Location: http://'.$host);
}
// otherwise, take them to another one of our sites and show them a descriptive message
else {
header('Location: http://www.anothersite.com/some_message');
}
?>
How can I replicate something like this on my page?

Based on the comments on the question, fsockopen() is the simplest and most widely available way to accomplish this task.
<?php
// Host name or IP to check
$host = 'www.example.com';
// Number of seconds to wait for a response from remote host
$timeout = 2;
// TCP port to connect to
$port = 25565;
// Try and connect
if ($sock = fsockopen($host, $port, $errNo, $errStr, $timeout)) {
// Connected successfully
$up = TRUE;
fclose($sock); // Drop connection immediately for tidiness
} else {
// Connection failed
$up = FALSE;
}
// Display something
if ($up) {
echo "The server at $host:$port is up and running :-D";
} else {
echo "I couldn't connect to the server at $host:$port within $timeout seconds :-(<br>\nThe error I got was $errNo: $errStr";
}
Note that all this does is test whether the server is accepting connections on TCP:25565. It does not do anything to verify that the application listening on this port is actually the application you are looking for, or that it is functioning correctly.

Related

How to check whether server IP status is up or down in PHP

I am creating a web application where I will be adding 10-20 IP addresses and setting a cron job for every 1 hour, that can be done easily. The problem is that I want to check whether an IP is currently working or not. If the IP is not working then I will get a message by email or some other mode. I have found the below code on the Internet:
$ip= '103.117.231.160';
$port = 80;
$fp = #fsockopen($ip, $port, $errno, $errstr, 2);
if (!$fp) {
echo 'offline';
} else{
echo 'online';
}
I have added many random IPs, but it's giving me online for the status. Is the above script fine or do I need to change the script? How can I test that an IP is working or not? Can anyone provide sample test IPs so I can make sure the script is working fine?
I just need correct output via email that my server is down.

Redirection of IP to Minecraft server with PHP

I have a local Minecraft Server set up. I decided to get myself my own domain, because ips arent really pretty. The problem is, that because the ip address of my router changes every night, I can't just do a A-record to my ip address. Instead I need a dynamic dns provider which allows me the use of my own domain. I could not seem to find one, so I coded it by myself with php (I have a free web server with a static ip address). Here's the code of the .php-file:
<?
$usernameTest = $_GET["username"];
$passTest = $_GET["pass"];
$ipaddr = $_GET["ipaddr"];
$username = "USERNAME";
$pass = "*****";
$port = ":25565";
$serverIPtxt = "serverIP.txt";
if(file_exists($serverIPtxt)) {
if($usernameTest == $username) {
if($passTest == $pass) {
$a = fopen("$serverIPtxt", "w");
fwrite($a, $ipaddr);
fclose($a);
echo $ipaddr;
}
} else {
$a = fopen("$serverIPtxt", "r+");
$dynIP = fread($a, filesize($serverIPtxt));
fclose($a);
$url="http://".$dynIP."".$port;
header("Location: $url", true);
die();
}
}
?>
My router is automaticly applying the correct ip address, so in theory I should be able to connect to the minecraft server with my new domain, but I cant. Instead Minecraft gives me this error:
[13:52:38] [Client thread/INFO]: Connecting to DOMAIN, 25565
[13:52:39] [Server Connector #5/ERROR]: Couldn't connect to server
java.net.ConnectException: Connection refused: no further information: DOMAIN/IPADDRESS:25565
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) ~[?:1.8.0_25]
at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:716) ~[?:1.8.0_25]
at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:208) ~[NioSocketChannel.class:4.0.23.Final]
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:287) ~[AbstractNioChannel$AbstractNioUnsafe.class:4.0.23.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:528) ~[NioEventLoop.class:4.0.23.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468) ~[NioEventLoop.class:4.0.23.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382) ~[NioEventLoop.class:4.0.23.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354) ~[NioEventLoop.class:4.0.23.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) ~[SingleThreadEventExecutor$2.class:4.0.23.Final]
at java.lang.Thread.run(Thread.java:745) ~[?:1.8.0_25]
What am I doing wrong? Or does Minecraft just not support php redirects?
Minecraft does not use HTTP! It uses its own protocol based on TCP.
The best option, which I have used in the past, is to run a dynamic ip updater client.
Get yourself a No-IP domain name (e.g. myname.ddns.net)
Download the dynamic updater client (available for Windows, Mac or Linux)
Set your custom domain name as a CNAME to point to myname.ddns.net (your NoIP domain name)
Give players your custom domain name (e.g. myname.com). This will refer the client to myname.ddns.net through the CNAME record which will in turn refer to your dynamic IP (e.g. xxx.xxx.xxx.xxx) as an A record.
After this you will be able to connect to your server with your custom domain and the dynamic updater will keep the dynamic IP up to date automatically.

Going about programming a minecraft server status checking program

I'm wanting to make a program which allows for me to check the status of Minecraft servers whether they're online, offline or full. How would I go about doing so? I'm thinking PHP server side, Python client side and SQL as server?
I need some major advice on what needs to be done to achieve such a task.
You don't need a database. Ping the server. If it responds, it's up...display a large green checkmark. If it doesn't respond...it's down. Display a large red x. You can do that in the FB API or in plain PHP anywhere.
See this question, which provides the following code:
function ping($host, $port, $timeout)
{
$tB = microtime(true);
$fP = fSockOpen($host, $port, $errno, $errstr, $timeout);
if (!$fP) { return "down"; }
$tA = microtime(true);
return round((($tA - $tB) * 1000), 0)." ms";
}
Notably if you want more information than just the server up/down status you can use the MineQuery protocol that most servers have enabled.
More info # DinnerBone's tool.
This will allow you to get the current/max players, MOTD, game version, and some other details if the server uses CraftBukkit.
Also this version written in PHP.

time out problem with gethostbyaddr() function in php

recently i noticed that on my new server the gethostbyaddr() function which is used on my site to get the referes' hosts, it makes the page load 5 times slower.
and when I removed it the time out problem is gone
what is wrong with this function and my new Centos linux server config.
and what else i can use instead of this php function to get the host name of my referers.
It may be a temporary slowness in DNS resolution and it may clear itself up later. There really isn't any alternative to gethostbyaddr() other than to make a system call like the following from PHP. (gethostbyaddr() does essentially this anyway)
`nslookup $ip_address`
// Or
`host $ip_address`
You can test to see if resolutions are slow from the command line with :
# choose an IP address you know the resolution of...
$ host 123.123.123.123
If this doesn't return quickly you may have a DNS problem.
Check the contents of /etc/resolv.conf and if you have an alternate DNS server you can point it to, try that one instead.
I wrote this useful replacement for gethostbyaddr():
//faster alternative to gethostbyaddr()
private function gethost( $ip )
{
//Make sure the input is not going to do anything unexpected
//IPs must be in the form x.x.x.x with each x as a number
if( preg_match( '/^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:[.](?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/', $ip ) )
{
$host = `host -s -W 1 $ip`;
$host = ( $host ? end( explode( ' ', trim( trim( $host ), '.' ) ) ) : $ip );
if( in_array( $host, Array( 'reached', 'record', '2(SERVFAIL)', '3(NXDOMAIN)' ) ) )
{
return sprintf( '(error fetching domain name for %s)', $ip );
}
else
{
return $host;
}
}
else
{
return '(invalid IP address)';
}
}
The trick is to use the host function, but you have to check if the $ip is a real IP to avoid exploits.
I set the timout to 1 second.
It's much faster than using gethostbyaddr, although it is still slow when used in a loop.
What kind of web hosting do you have? Shared, VPS or dedicated. gethostbyaddr() performance is dependent on how effective your web server DNS resolution is. There are some scenarios which might decrease its performance but you would still need to say at least what type of hosting you are using.
I think you should just implement some type of caching system for gethostbyaddr() results (Well, most of DNS servers have built-in caching system, but your can malfunction for some reason) or try to use alternative DNS servers(with system call or better with PHP's sockets).
Unfortunately some isp's don't maintain reverse dns records for some ip addresses, and therefore a dns lookup will always fail. The problem is how long to wait before giving it up.
Some hosting services set the gethostbyaddr function timeout real short, and if a lookup isn't successful, the ip address will be substituted for the host name. This speeds things up, preventing long delays in displaying pages that call this function.
You should always scrutinize log entries that don't show host names, as they rather frequently indicate that the visitor is from an ip address with a reputation for nefarious Internet activity.
As gethostbyaddr() does not support timeouts and my hosting setup does not allow shell commands I decided to use a local API:
<?php
$ip = isset($_GET['ip']) ? filter_var($_GET['ip'], FILTER_VALIDATE_IP) : false;
if ($ip) {
echo json_encode(gethostbyaddr($ip));
}
?>
And now I send a request to this hostAPI.php through file_get_contents() as follows:
<?php
// prepare host url
function isSecure() {
return ((isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443) ? 's' : '';
}
$protocol_host = 'http' . isSecure() . '://' . filter_input(INPUT_SERVER, 'HTTP_HOST', FILTER_SANITIZE_URL);
// dns request
$context = stream_context_create(array(
'http' => array(
'timeout' => 0.4,// 400 ms
)
));
$ip = long2ip(mt_rand(0, "4294967295"));
// note: the host url needs public access!
$host = json_decode(#file_get_contents($protocol_host . '/hostAPI.php?ip=' . $ip, false, $context), true);
// output
echo 'IP: ' . $ip . "<br>\n";
echo 'HOST: ' . ($host ? $host : 'Timeout!') . "<br>\n";
echo 'Execution Time: ' . round((microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]) * 1000) . ' ms';
?>
As you can see I set the timeout through stream_context_create().
Sample output:
IP: 56.152.200.204
HOST: Timeout!
Execution Time: 801 ms
IP: 81.139.131.130
HOST: host81-139-131-130.range81-139.btcentralplus.com
Execution Time: 52 ms
I do not know why, but on my setup the 0.4 timeout kicks in after > 800 ms so I needed to double the value to get the final timeout. Maybe someone else can comment that.
Warning
This creates one additional http request on your server for every request on your main script!
After upgrading from XP to 7 it effected PHP's handling of IPv4 versus IPv6 (e.g. 127.0.0.1 is returned as ::1) I had adapted some code to temporarily address this issue. It turns out that I was using gethostbyaddr on the IPv6 patch and thus it was getting stuck timing out for PHP.
Before...
$ip = ip2long6($ip);
$host = gethostbyaddr($ip);
After...
$host = gethostbyaddr($_SERVER['REMOTE_ADDR']);
You can use Xdebug and WinCacheGrind (I use XAMPP for local testing) to find what is timing out, here is a video tutorial for a quick run-through...
http://www.warpconduit.net/2012/09/01/quick-tip-profiling-php-applications-with-xdebug-wincachegrind-xampp-for-windows/
Hope this saves someone some sanity. :-)

Pinging CS Servers

This has been bothering me for awhile, can some one show me how to ping a counter strike server.
I just want to ping the server and see if it is online, thats all.
I found many small snippets online that were using fsock and UDP to do this but none of them actually did the job i wanted it to do.
Most of the ones i found were showing offline servers as online.
I would really really appreciate if some one could provide me with this useful information (code).
Thank you in advance ^_^
you can't just ping the server since it uses UDP instead of normal TCP, so in order to check it's status you need to "query" the server, you can find information about what command you can send to CS servers here: http://developer.valvesoftware.com/wiki/Server_queries#A2A_PING
Anyway the following code (PHP) can be used to check CS server status.
`
`
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_connect($socket, "cs.somesv.com", 27015);
socket_write($socket, "\xFF\xFF\xFF\xFF\x69");
if (#socket_read($socket, 5) == "\xFF\xFF\xFF\xFF\x6A") {
echo '<FONT COLOR=lime>Online</FONT>';
} else {
echo '<FONT COLOR=red>Offline</FONT>';
}
socket_close($socket);
?>`
Bah! this code blocks don't really work fine! :(
Anyway, I use this code everyday for my server, hope it works fine for you.
Two choices off the top of my head:
fsockopen:
http://www.phptoys.com/e107_plugins/content/content.php?content.41
Net_Ping Pear package:
http://www.codediesel.com/php/ping-a-server-using-php/
Using IP of the CS server.
Get ClanManager and it has modules to check status of CS server.
This is the file with examples talking with CS servers,
http://clanmanager.cvs.sourceforge.net/viewvc/clanmanager/ocm/server/counterstrike.inc?revision=1.3&view=markup
You can also do what's known as a TCP ping. Basically, you just connect then disconnect without any communication. If the connection succeeds, you know the server is up, if it fails it's down. When I say server I mean the program you're interested in, not the physical server.
Here is PHP function to check if CS server is online:
function isCsServerOnline($server, $port = 27015)
{
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
// timeout 1.5 seconds
$timeout = array('sec' => 1, 'usec' => 500000);
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, $timeout);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, $timeout);
#socket_connect($socket, $server, $port);
#socket_write($socket, "\xFF\xFF\xFF\xFF\x69");
$isOnline = #socket_read($socket, 5) == "\xFF\xFF\xFF\xFF\x6A";
#socket_close($socket);
return $isOnline;
}
You can use it like this:
$server = 'some.cs.server';
$port = 27015;
$isOnline = isCsServerOnline($server, $port);
echo $isOnline ? 'Online' : 'Offline';

Categories