PHP Server Ping

Discussion in 'Bukkit Tools' started by nisovin, Sep 14, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    nisovin

    Since 1.8 servers can now respond to ping requests, I decided to try to make a PHP script that will ping the server and get the number of players online. Keep in mind that I've never done anything with sockets in PHP before, so if someone sees something wrong or bad, please let me know.

    Code:
    $host = "hostnamehere.com";
    $port = 25565;
    
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    $connected = socket_connect($socket, $host, $port);
    if ($connected) {
        socket_send($socket, "\xFE", 1, 0);
        $data = "";
        $result = socket_recv($socket, &$data, 50, 0);
        socket_close($socket);
        if ($result != false && substr($data, 0, 1) == "\xFF") {
            $info = explode("\xA7", mb_convert_encoding(substr($data,1), "iso-8859-1", "utf-16be"));
            $serverName = substr($info[0], 1);
            $playersOnline = $info[1];
            $playersMax = $info[2];
            echo "Server: $serverName<br/>Players Online: $playersOnline/$playersMax";
        } else {
            echo "Failed to receive data";
        }
    } else {
        echo "Failed to connect";
    }
    
    I'm unsure about the character decoding, but it seems to work. Also, there was a character in the server name (0x15) that I cut off, not sure why that is there. Otherwise it seems to work great.
     
  2. Offline

    Bazinga

    Just had to try it out to see what ifo the server did send. Not much as it turns out. :(
    Would have been nice to see a whitelist flag.

    I did add a ping measurement. Seems it shows way of compared to the ingame measurement u get on the serverlist.
    To the server I tried it to i get about 25/30ms with ingame browser(some odd high/low) but with the php query i get even better but mostly worse. It does jump around :confused:.

    Either way it was just a test. Dunno why the ping gets so random values.


    PHP:
    $host "XXXXXXXXXX";
    $port 25565;

    $socket socket_create(AF_INETSOCK_STREAMSOL_TCP);
    $connected socket_connect($socket$host$port);
    if (
    $connected) {
        
    $ping_start microtime(true);
        
    socket_send($socket"\xFE"10);
        
    $data "";
        
    $result socket_recv($socket, &$data500);$ping_end microtime(true);
        
    socket_close($socket);

        if (
    $result != false && substr($data01) == "\xFF") {
            
    $info explode("\xA7"mb_convert_encoding(substr($data,1), "iso-8859-1""utf-16be"));
            
    $serverName substr($info[0], 1);
            
    $playersOnline $info[1];
            
    $playersMax $info[2];
            
    $ping round(($ping_end $ping_start) * 1000);
            echo     
    "Server: $serverName<br/>
                    Address: 
    $host<br/>
                    Port: 
    $port<br/>
                    Players Online: 
    $playersOnline/$playersMax <br/>
                    Ping: 
    $ping ms<br/>";
        } else {
            echo 
    "Failed to receive data";
        }
    } else {
        echo 
    "Failed to connect";
    }

    Just tried some long motd messages. seems 50 is a bit short and you would risk loosing maxplayerinfo or more from the string.

    I would recommend changing 50 to 150 in this row..
    PHP:
    $result socket_recv($socket, &$data1500);
    Long motd mess up ingame serverinfo to. Regardless off gui scale chosen.
    150 should be enough to show all needed.
     
  3. Offline

    gbear605

    With both of them, I get:



    This happened with a server that might be on or off, and it happened with a server that was on. What do you think's wrong?
     
  4. Offline

    Drakia

    The socket functions require that php_sockets.dll be enabled under Windows. Here is a modification that does not require this:

    Code:
    <?php
    	$host = "example.com";
    	$port = 25565;
    
    	$socket = @fsockopen($host, $port);
    	if ($socket !== false) {
    		@fwrite($socket, "\xFE");
    		$data = "";
    		$data = @fread($socket, 1024);
    		@fclose($socket);
    		if ($data !== false && substr($data, 0, 1) == "\xFF") {
    			$info = explode("\xA7", mb_convert_encoding(substr($data,1), "iso-8859-1", "utf-16be"));
    			$serverName = substr($info[0], 1);
    			$playersOnline = $info[1];
    			$playersMax = $info[2];
    			echo "Server: $serverName<br/>Players Online: $playersOnline/$playersMax";
    		} else {
    			// Server did not send back proper data, or reading from socket failed.
    			echo "Failed to receive data";
    		}
    	} else {
    		// Can't connect. Server is probably down.
    		echo "Failed to connect";
    	}
    ?>
     
  5. Offline

    gbear605

    Hmm, I Tried the new version, and the socket part worked, except that a server that I know is up (I'm on it) is giving the failed to connect message.
     
  6. Offline

    Borch

    You're doing it wrong.
    What you think is a "strange character" before the server name is actually the length field. Before you do the conversion from utf-16 it's two bytes, a 16 bit signed integer in big endian format, that tells you how many bytes the following string has.
     
  7. Offline

    Sna.ke

    Is there a firewall blocking the PHP server from establishing a connection out (Windows Firewall enabled?).

    Is this hosted locally or with a hosting provider? A lot of web hosts restrict outbound access from websites and require you to request ports to be opened.
     
  8. Offline

    gbear605

    Hosting provider. I wouldn't think about the port thing, mainly because i am paying a huge amount of money for it. It isn't a firewall I think.
     
  9. Offline

    Drakia

    He means web host
     
  10. Offline

    Sna.ke

    Most hosting providers restrict outbound ports nowadays on the web server.

    Most websites only need to connect to 80, 25, 443, 3306 and a handful of others. Just contact your hosting provider and ask them to make sure the outbound port is open.
     
  11. Offline

    gbear605

    D: My hoster won't let me do that.
     
  12. Offline

    JustinGuy

    Looks good, thanks for the script I was looking for something simple to check if my server was up and this was it! With PHP i always recommend you develop with strict error reporting (a simple error_reporting(E_ALL); at the top of your script will do fine). On the socket_recv you need to remove the `&` from in front of the buf variable, call time pass by reference was depreciated and removing it will still provide the same behavior you were expecting. :)
     
  13. Offline

    alexanderpas

    nope, E_STRICT only became part of E_ALL in PHP 5.4 (the latest stable is in the PHP 5.3 series)

    The PHP documentation suggest using error_reporting(-1);
     
  14. Offline

    oxguy3

Thread Status:
Not open for further replies.

Share This Page