Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

DfsmvPorty - XML-configurable Port Scanner

0.00/5 (No votes)
9 May 2003 2  
A small utility to notify you by e-mail when ports on servers are not available.

Example output of a run of DfsmvPorty
Image: Example output of a run of DfsmvPorty (in an OS X-style color)

Introduction

Following my series of command-line-driven applications, this is another small utility that is hopefully useful to you or at least is an inspiration for your own ideas and enhancements.

The purpose of the application is simply to check one or multiple ports on one or multiple servers to be accessible.

The original usage of the application was to monitor server downtimes for a customer of ours. Since sometimes only certain services (like e.g. Citrix, IIS) where unavailable I wrote this application, together with Harald.

Installation

DfsmvPorty is a Microsoft .NET console application with no graphical UI (GUI). To "install" this application, all you have to do is to copy the application into an arbitrary folder, e.g. "C:\Program Files\DfsmvPorty".

Configuration

The DfsmvPorty application is driven by XML configuration files, which tell the application which servers and which ports to scan. In the downloads of this article, you find a file "Example.dfsmvp" which contains lots of comments on how to use the different sections of the application.

Here is a minimal example XML file (without comments, for better readability) that shows you the syntax:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

    <settings
        mailServer="neleus"
        mailSenderEMailAddress="uk@zeta-software.de"
        mailPortNotAvailableSubject="[DfsmvPorty] $(Now): Some Ports 
            on Host '$(HostName)' did not respond"

        loopCount="1"
        loopIntervalSeconds="30"

        waitEndKey="true"
    >

        <mailNotAvailableBody><![CDATA[The following ports on host 
            '$(HostName)' did not respond:
            $(Ports)
        ]]></mailNotAvailableBody>

        <mailNotAvailableBodyPort><![CDATA[Port '$(Port)', error 
            message: $(ErrorMessage).
        ]]></mailNotAvailableBodyPort>
    </settings>

    <servers>
        <server
            address="www.codeproject.com"
            isActive="true"
            >

            <mailReceiverEMailAddresses>
                <address address="uk@zeta-software.de"/>
                <address address="uwe@magerquark.de"/>
            </mailReceiverEMailAddresses>

            <ports>
                <port number="80"/>
                <port number="110"/>
            </ports>
        </server>
    </servers>
</configuration>

You pass a configuration file to the DfsmvPorty application by simply specifying the name (and optionally the path) of the configuration file as a command line parameter. E.g.:

C:\Program Files\DfsmvPorty\DfsmvPorty.exe MyServers.dfsmvp

The above code would execute the DfsmvPorty application with the configuration read from a file "MyServers.dfsmvp", process the configuration and then terminate.

The extension ".dfsmvp" is actually just for convenience; you can pass a file with any other extension (e.g. ".xml") to the DfsmvPorty application, as long as the content meets the requirements (again, see "Example.dfsmvp" in the downloads of this article).

Practical usage

The logic of the DfsmvPorty application is rather simple:

  1. You start the application with a XML configuration file, like described above
  2. The application reads the configuration file and processes the instructions
  3. If an error occurs (i.e. if a port is unavailable), the applications generates and sends one or multiple e-mail messages to the configured receivers
  4. The application terminates (or loops, depending on your configuration, see the following two sub-chapters)

"Real configuration" (1) - Looping done with Windows Task Scheduler

To be really useful, i.e. that you get a quick notice when your servers/ports are down, the application must be run periodically, e.g. every 5 minutes.

Therefore you can use the built-in Task Scheduler of Windows (on older Windows versions, the Internet Explorer installs this scheduler automatically).


Image: The Task Scheduler in the Windows Control Panel

To configure the Task Scheduler to run the DfsmvPorty application periodically, you can e.g. use the wizard of the Task Scheduler. The result of a successful run of this wizard could look like this:


Image: Property page of a scheduled task of the DfsmvPorty application, running the "MyServers.dfsmvp" XML-configuration file

Please ensure that you configure the user in the "Run as" to have sufficient permissions to actually execute the application. Possibly you need to adjust both Windows security settings and .NET security settings.

You can use the Advanced Schedule Options dialog box to further configure the application:


Image: The DfsmvPorty application configured to be started every 10 minutes

Once your done configuring the Task Scheduler, you can forget about the DfsmvPorty application since it now runs completely automatically.

"Real configuration" (2) - Looping done within the DfsmvPorty Application

You can also instruct the DfsmvPorty application to do the looping itself. This is done in the <settings> tag of the configuration file.

To configure the DfsmvPorty application for looping itself

  1. Set the loopCount attribute in the <settings> tag of the configuration file to "0" (zero) for endless looping.
  2. Set the loopIntervalSeconds attribute in the <settings> tag of the configuration file to the intervall (in seconds) to wait between two loops. E.g. set it to "600" to wait for 10 minutes.
  3. Configure the Task Scheduler as described above, except that you tell to start the task only once at system startup


Image: DfsmvPorty application, configured to run at system startup only

Once your done configuring the Task Scheduler, again, you can forget about the DfsmvPorty application since it now runs completely automatically.

Summary of the two Methods of configuring the DfsmvPorty Application

Depending on your preferences, you can either use the Windows Task Scheduler to run the DfsmvPorty application periodically (e.g. every 5 minutes) or to start the DfsmvPorty application only once and let the application do the periodical checking of the servers and ports by itself.

E-Mail Notifications

If ports are unavailable during a run of the DfsmvPorty application, an e-mail message is generated and sent to all configured receivers. The content of the e-mail message is configurable through the configuration file, too and the result might look like this:


Image: Received e-mail message from the DfsmvPorty application, informing about unavailable ports

If you receive such an e-mail message, you know that something seems to be wrong and probably you should hurry up and get things fixed...

Background

The code itself really is no rocket science; in fact there are only about four source files:

  • Application.cs for encapsulating the core application logic
  • Config.cs for making the read-in configuration file accessible as C# objects
  • Common\Logging.cs for encapsulating the logging to various destinations
  • Common\Smtp.cs for being able to send the notification e-mail messages via SMTP

The actual connection routine to a certain port on a certain server is in the file Config.cs in the function DfsmvPorty.Port.Process(). It does a System.Net.Socket.Connect() on a System.Net.IPEndPoint. If this connection fails, the application counts this as "port not available" and accumulates the port for the sending of the notification e-mail message.

Following is the code of the DfsmvPorty.Port.Process() function:

/// <summary>

/// This function does the actual connection to a port on a server.

/// </summary>

/// <param name="number">The number of the port to connect.</param>

private void Process( int number )
{
    Socket socket = new Socket( AddressFamily, SocketType, ProtocolType );
    IPEndPoint ep = new IPEndPoint( Owner.IP, number );

    try
    {
        socket.Connect( ep );
        if ( !socket.Connected )
        {
            // Socket not connected. Must notify user by e-mail.


            Exception = new Exception("Socket.Connect() returned false.");
            ExceptionPortNumber = number;
            OnCantConnect();
        }
        else
        {
            socket.Close();
        }
    }
    catch ( SocketException e )
    {
        // An exception occured. Must notify user by e-mail.


        Exception = e;
        ExceptionPortNumber = number;
        OnCantConnect();
    }
}

I'm unsure whether this is really a reliable and "professional" way of checking the availability of a port, but to me this was a working and reliable solution.

If you have any suggestions and comments on how to make it better and more error-proof, please write a comment below at the end of the article.

Conclusion

I hope this article is useful to you and you will give me some feedback.

Regarding the strange name of the application: this is a secret shortcut of a rather funny joke, Harald and I came across when we developed this application, and you can be sure that we never every tell anyone what "dfsmv" really means .

In case you wonder about the German text on some screenshots: Sorry for that! I only have limited access to English versions of Windows, so some texts are still in German; I hope you still understand most of the texts.

History

In ascending order:

  • 2003-05-10 Initial release

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here