• Home

Logo

Navigation
  • Home
  • Articles
    • Content Writing
    • Design
    • General
    • Internet Marketing
    • Social Media
    • Tools and Tips
    • Usability
    • Web Hosting Articles
  • Tutorials
    • AJAX Tutorials
    • ASP Tutorials
    • C# Tutorials
    • CGI and Perl Tutorials
    • CSS Tutorials
    • Flash Tutorials
    • HTML Tutorials
    • Illustrator Tutorials
    • Java Tutorials
    • JavaScript Tutorials
    • Linux Tutorials
    • Miscellaneous Tutorials
    • MySQL Tutorials
    • Photoshop Tutorials
    • PHP Tutorials
    • Python Tutorials
    • Wireless Tutorials
    • WordPress Tutorials
    • XML Tutorials
  • Scripts
    • AJAX Scripts
    • ASP Scripts
    • ASP.NET Scripts
    • CGI & Perl Scripts
    • Flash Scripts
    • Java Scripts
    • JavaScript Scripts
    • PHP Scripts
    • Python Scripts
    • Remotely Hosted
    • Tools and Utilities
    • XML Scripts
  • Answers
  • Online Services
  • Tools

Port Scanning and Service Status Checking in PHP

By Akash Mehta | on Jun 6, 2008 | 1 Comment
PHP Tutorials
  • Tweet
  • Share
  • Tweet
  • Share

Introduction

While building web applications, it’s often important to keep an eye on the other services running on your server. Having access to the current status of public servers can empower your applications to make decisions and respond to problems automatically. Acknowledging a service is offline can also save endless support emails. In this tutorial, I’ll show you how to keep track of your server status by scanning ports on your server with PHP.

What is server status?

A web application runs on a web server, such as the Apache HTTP server. However, your website often relies on many other “servers” on the same physical server – for example, your email servers, or your database server. Server status checking is commonly found in web hosting control panels, where it is crucial to be aware of the status of services:

Each of these services running on the server is listening on a particular port. We can easily check if the service is online by checking if it is still listening on that particular port. Should it be offline for any reason, we will simply receive no response on that port.

You will be familiar with a simple manual approach for checking the Apache HTTP server – the server by default listens on port 80; if it is offline, a web browser attempting to connect to it will receive no response and will display an error message to the user. You can check your websites are online by attempting to visit them in a web browser. In this tutorial, we will simply automate this process and develop a powerful means for examining server status at a glance.

Service Checking 101

We will be using the PHP function fsockopen() to attempt to open a connection to the port we want to check. If the connection fails, the function will return false. The function also has options to return an error number and an error string if the connection fails. However, a connection does not technically “fail” in a network – or, at least, that is not what we are checking. If the service is offline, the server will simply not respond to the connection and the connection will timeout. We specify how long we want to wait till the connection is considered timed out using a parameter to the function.

Fire up your favourite text editor and copy in the following:

<?php
$connection = @fsockopen("www.google.com", 80);
if ($connection) {
    echo "Port 80 on www.google.com is open.";
    fclose($connection);
} else {
    echo "Port 80 on www.google.com is not open.";
}

In this snippet, we call fsockopen and ask it to open a connection to “www.google.com” on port 80. If the connection is established – fsockopen indicates this by returning a non-false value – we display an appropriate status message, and likewise if the connection is not established. In a variety of situations, the function will output an error message, and so we use the @ symbol before the function name to suppress errors generated.

The function actually returns a handle on a socket connection established, a reference by which you can tell the other socket functions to manipulate this particular connection. In this case, if the connection is established, we need to close the connection, or we could soon overload the server (ours, and theirs!) with an excess of open connections. We achieve this using the fclose function.

Port scanning

As this method is simply checking a particular port on the server, we can easily scan for a number of ports on the server using a simple for loop. This method is known as port scanning. Often a server will be running a range of web-facing services, and server scanning allows server operators to scan for services they may not be aware of. Any web-facing software can bring with it additional security risks, and so port scanning is a popular part of security testing. If we wanted to check all the ports between 1 and 1000 on localhost, we could do this with just a few lines of code:

<?php
for($i=1;$i<=1000;$i++) {
    $conn = @fsockopen("localhost", $i);
    if ($conn) {
        echo "Port $i is open.n";
        fclose($conn);
    }
}

A simple yet effective implementation.

Our Implementation

To produce something similar to the server status screenshot we saw earlier, we’ll build a simple function to test a given port on the local machine. We’ll then incorporate it into a very basic status interface.

In a production scenario, make sure your testing script is on another server. If your web server goes down, your testing script will as well; if your network is experiencing problems, your testing script will not be able to detect these when scanning the local machine. We’ll use localhost in this example for simplicity’s sake, but seperate hosting for a testing script is crucial in production.

Working with sockets

We can easily give fsockopen a hostname, but we can also give it an IP address. In this case, we probably want to check the local server’s status, but checking service status on a remote server is also an option. We’ll use 127.0.0.1 to check the local server. We also need to make sure we close each connection if we succesfully establish it.

We can build the socket code in a very simple function similar to the port scanning example:

<?php
function check_port($port) {
    $conn = @fsockopen("127.0.0.1", $port, $errno, $errstr, 2);
    if ($conn) {
        fclose($conn);
        return true;
    }
}

Here we have added a few parameters to the fsockopen function call. The first two, for the error number and string, point to variables that the function can use to store the respective error information. Most important, however, is the ’2′ at the end – this is the timeout for the connection in seconds. If the connection isn’t established in 2 seconds (which should be more than enough for a local connection), the connection attempt is aborted and considered a failure. Keep in mind that, for each service that is offline, the system will wait a further 2 seconds before generating the report. If your page is taking too long to load, the end user may suspect the entire server is offline!

Checking the services

Now, this will do our standard test on whether or not a connection can be established to the local server on the given port. Next, we need a simple system to check for common ports. We can hardcode this section – we’ll always know what we want to check for. Here are some common ports you might want to watch out for:

21 FTP
22 SSH
25 SMTP
80 HTTP
110 POP3
143 IMAP
3306 MySQL

This page has a good list of common ports you may find useful.

We can encode these in a simple associative array within a secondary function that generates the status output as another array.

<?php
function server_report() {
    $report = array();
    $svcs = array('21'=>'FTP',
                  '22'=>'SSH',
                  '25'=>'SMTP',
                  '80'=>'HTTP',
                  '110'=>'POP3',
                  '143'=>'IMAP',
                  '3306'=>'MySQL');
    foreach ($svcs as $port=>$service) {
        $report[$service] = check_port($port);
    }
    return $report;
}

$report = server_report();

Using the data

Once this code executes (given the previous check_port function), our $report variable now holds an associative array indexed by the name of the service, with a value of either true or false (well, 0 or 1). We can then very easily display this in a table:

<table>
    <tr>
        <td>Service</td>
        <td>Status</td>
    </tr>
    <tr>
        <td>FTP</td>
        <td><?php echo $report['FTP'] ? "Online" : "Offline"; ?></td>
    </tr>
    <tr>
        <td>SSH</td>
        <td><?php echo $report['SSH'] ? "Online" : "Offline"; ?></td>
    </tr>
    ...
</table>

And so on. Now that we have a basic system in place, we can easily introduce visual status indicators (e.g. green / red light icons), or do more with the data (e.g. logging).

We’re done!

Here’s the completed code:

<?php
function check_port($port) {
    $conn = @fsockopen("127.0.0.1", $port, $errno, $errstr, 0.2);
    if ($conn) {
        fclose($conn);
        return true;
    }
}

function server_report() {
    $report = array();
    $svcs = array('21'=>'FTP',
                  '22'=>'SSH',
                  '25'=>'SMTP',
                  '80'=>'HTTP',
                  '110'=>'POP3',
                  '143'=>'IMAP',
                  '3306'=>'MySQL');
    foreach ($svcs as $port=>$service) {
        $report[$service] = check_port($port);
    }
    return $report;
}

$report = server_report();
?>
<table>
    <tr>
        <td>Service</td>
        <td>Status</td>
    </tr>
    <tr>
        <td>FTP</td>
        <td><?php echo $report['FTP'] ? "Online" : "Offline"; ?></td>
    </tr>
    <tr>
        <td>SSH</td>
        <td><?php echo $report['SSH'] ? "Online" : "Offline"; ?></td>
    </tr>
    <tr>
        <td>SMTP</td>
        <td><?php echo $report['SMTP'] ? "Online" : "Offline"; ?></td>
    </tr>
    <tr>
        <td>HTTP</td>
        <td><?php echo $report['HTTP'] ? "Online" : "Offline"; ?></td>
    </tr>
    <tr>
        <td>POP3</td>
        <td><?php echo $report['POP3'] ? "Online" : "Offline"; ?></td>
    </tr>
    <tr>
        <td>IMAP</td>
        <td><?php echo $report['IMAP'] ? "Online" : "Offline"; ?></td>
    </tr>
    <tr>
        <td>MySQL</td>
        <td><?php echo $report['MySQL'] ? "Online" : "Offline"; ?></td>
    </tr>
</table>

In a production application, you can easily abstract the status checking logic from the report HTML and store service info in a database.

Advanced Status Checking

Now that we’ve built a basic service status checker, we can easily extend it conduct more rigorous testing, and make better use of the data. Here are some possibilities for extending this script:

  • Log service data; it can then be graphed or simply archived for auditing
  • Report downtime to you, e.g. via email or SMS
  • Conduct service-specific testing, e.g. download a HTML page, run a MySQL query, start an FTP session

I mentioned earlier the importance of hosting your testing script away from your actual server; if your project warrants it, storing a testing script on two different servers is great for redundancy, and the two can even work hand in hand to verify if a supposed outage is only region-specific, e.g. a server in the UK might report downtime while a server in the US does not. This can also aid in tracking down the cause of downtime when networks are involved.

Experiment with these techniques, explore additional testing methods and you could be building business-grade status checking systems in no time at all!

Share this story:
  • tweet

Author Description

Akash Mehta is a web solutions consultant and application developer. He regularly advises website owners and small business on their online challenges, while researching and writing on innovative uses of web-related technologies for the developer community. In his copious free time, he enjoys cycling and investigating creative accounting methods.

One Response to “Port Scanning and Service Status Checking in PHP”

  1. October 10, 2010

    Enzo Kun Log in to Reply

    how to use instead of text online and offline
    how about image

You must be logged in to post a comment.

Connect With Us

RSSSubscribe 0Followers 494Likes
  • Popular
  • Recent
  • Comments
  • Creating Energy Spheres in Photoshop

    Apr 15, 2008 - 96 Comments
  • Easy Screen Scraping in PHP with the Simple HTML DOM Library

    Aug 6, 2008 - 20 Comments
  • Calculating date difference more precisely in PHP

    Mar 7, 2008 - 13 Comments
  • When Does Hosting Your Website in the Cloud Make Sense?

    Oct 8, 2010 - 2 Comments
  • Fun with the Microsoft Managed Extensibility Framework Part 2

    Oct 6, 2010 - 0 Comment
  • Fun with the Microsoft Managed Extensibility Framework Part 1

    Sep 22, 2010 - 0 Comment
  • Website Management on the go with the iPad

    I appreciated your post, but I was looking for something I didn't...
    November 24, 2012 - drmoderator
  • Creating Energy Spheres in Photoshop

    I'm a little stuck down here especially at the step of creating the...
    November 23, 2012 - sarah
  • Running background processes in PHP

    Can you give an example? As see it, you can use this only when you...
    November 16, 2012 - Shaked Klein Orbach
Developer Resources
  • Tutorial Directory
  • Learn HTML
  • Learn PHP
  • Learn CSS
  • Learn AJAX
  • Learn JavaScript
  • Learn Pear
  • White Papers
  • Resources
    • NetVisits Web Directory
    • Realtor Pixels
    • Answers On The Run
    • Ask A Geek
  • Recent Posts

    • When Does Hosting Your Website in the Cloud Make Sense?
    • Fun with the Microsoft Managed Extensibility Framework Part 2
    • Fun with the Microsoft Managed Extensibility Framework Part 1
    • Website Management on the go with the iPad
    • Code Contracts in C# 4.0 – Part 1

    Calendar

    May 2013
    M T W T F S S
    « Oct    
     12345
    6789101112
    13141516171819
    20212223242526
    2728293031  

    Recent Comments

    • drmoderator on Website Management on the go with the iPad
    • sarah on Creating Energy Spheres in Photoshop
    • Shaked Klein Orbach on Running background processes in PHP
    • Thomas Cuvillier on How To Upload Files Using PHP
    • rizal aditya on Extracting text from Word Documents via PHP and COM
    • Home
    © 2003 - 2013 DeveloperTutorials.com. All Rights Reserved. Privacy Policy.