65.9K
CodeProject 正在变化。 阅读更多。
Home

DfsmvPorty - XML可配置的端口扫描器

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.67/5 (24投票s)

2003年5月10日

CPOL

6分钟阅读

viewsIcon

63641

downloadIcon

1311

一个小型实用程序,可在服务器端口不可用时通过电子邮件通知您。

Example output of a run of DfsmvPorty
图片:DfsmvPorty 运行的示例输出(OS X 风格的颜色)

引言

继我一系列的命令行驱动的应用程序之后,这是另一个小型实用程序,希望对您有所帮助,或者至少能激发您自己的想法和改进。

该应用程序的目的是简单地检查一个或多个服务器上一个或多个端口是否可访问。

该应用程序的原始用途是为我们的客户监控服务器停机时间。由于有时只有特定的服务(例如 Citrix、IIS)不可用,因此我与Harald一起编写了此应用程序。

安装

DfsmvPorty 是一个 Microsoft .NET 控制台应用程序,没有图形用户界面 (GUI)。要“安装”此应用程序,您所要做的就是将应用程序复制到任意文件夹,例如“C:\Program Files\DfsmvPorty”。

配置

DfsmvPorty 应用程序由 XML 配置文件驱动,这些配置文件告诉应用程序要扫描哪些服务器和端口。在本篇文章的下载文件中,您会找到一个名为“Example.dfsmvp”的文件,其中包含大量关于如何使用应用程序不同部分的注释。

这是一个最小的示例 XML 文件(无注释,为了更好的可读性),展示了语法。

<?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>

您可以通过简单地将配置文件名(以及可选路径)作为命令行参数传递给 DfsmvPorty 应用程序。例如:

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

上面的代码将使用从“MyServers.dfsmvp”文件读取的配置来执行 DfsmvPorty 应用程序,处理配置,然后终止。

“.dfsmvp”扩展名实际上只是为了方便;您可以传递任何其他扩展名的文件(例如“.xml”),只要其内容符合要求(同样,请参阅本文下载中的“Example.dfsmvp”)。

实际使用

DfsmvPorty 应用程序的逻辑相当简单:

  1. 如上所述,您使用 XML 配置文件启动应用程序。
  2. 应用程序读取配置文件并处理指令。
  3. 如果发生错误(即端口不可用),应用程序将生成并向配置的接收者发送一个或多个电子邮件消息。
  4. 应用程序终止(或循环,取决于您的配置,请参阅以下两个子章节)。

“实际配置” (1) - 使用 Windows 任务计划程序进行循环

为了真正有用,即当您的服务器/端口出现故障时,您能得到*快速*通知,该应用程序必须定期运行,例如每 5 分钟一次。

因此,您可以使用 Windows 内置的**任务计划程序**(在较旧的 Windows 版本中,Internet Explorer 会自动安装此计划程序)。


图片:Windows 控制面板中的任务计划程序

要配置任务计划程序定期运行 DfsmvPorty 应用程序,您可以使用任务计划程序的向导。此向导成功运行的结果可能如下所示:


图片:DfsmvPorty 应用程序计划任务的属性页,正在运行“MyServers.dfsmvp”XML 配置文件。

请确保在“运行身份”中配置的用户具有执行应用程序的足够权限。您可能需要同时调整 Windows 安全设置和 .NET 安全设置。

您可以使用“高级计划选项”对话框进一步配置应用程序。


图片:DfsmvPorty 应用程序配置为每 10 分钟启动一次。

完成任务计划程序的配置后,您可以忘记 DfsmvPorty 应用程序,因为它现在完全自动运行。

“实际配置” (2) - 在 DfsmvPorty 应用程序内部进行循环

您也可以指示 DfsmvPorty 应用程序自己进行循环。这在配置文件中的<settings>标签中完成。

配置 DfsmvPorty 应用程序进行自身循环:

  1. 将配置文件<settings>标签中的loopCount属性设置为“0”(零)表示无限循环。
  2. 将配置文件<settings>标签中的loopIntervalSeconds属性设置为两次循环之间等待的时间间隔(以秒为单位)。例如,设置为“600”表示等待 10 分钟。
  3. 如上所述配置任务计划程序,但指示它仅在系统启动时启动一次任务。


图片:DfsmvPorty 应用程序,配置为仅在系统启动时运行。

完成任务计划程序的配置后,同样,您可以忘记 DfsmvPorty 应用程序,因为它现在完全自动运行。

DfsmvPorty 应用程序两种配置方法的总结

根据您的偏好,您可以选择使用 Windows 任务计划程序定期运行 DfsmvPorty 应用程序(例如,每 5 分钟一次),或者仅启动 DfsmvPorty 应用程序一次,让应用程序自己进行服务器和端口的周期性检查。

电子邮件通知

如果在 DfsmvPorty 应用程序运行期间端口不可用,将生成电子邮件消息并发送给所有配置的接收者。电子邮件消息的内容也可以通过配置文件进行配置,结果可能如下所示:


图片:从 DfsmvPorty 应用程序收到的电子邮件消息,告知端口不可用。

如果您收到这样的电子邮件消息,您就知道有些事情似乎出了问题,并且您可能应该赶紧修复它……

背景

代码本身确实不是什么高科技;事实上,只有大约四个源文件:

  • Application.cs 用于封装核心应用程序逻辑。
  • Config.cs 用于将读取的配置文件作为 C# 对象访问。
  • Common\Logging.cs 用于封装到各种目标的日志记录。
  • Common\Smtp.cs 用于通过 SMTP 发送通知电子邮件消息。

连接到特定服务器上的特定端口的实际例程位于 Config.cs 文件中的 DfsmvPorty.Port.Process() 函数中。它会在 System.Net.IPEndPoint 上执行 System.Net.Socket.Connect()。如果此连接失败,应用程序将此视为“端口不可用”,并累积该端口以发送通知电子邮件消息。

以下是 DfsmvPorty.Port.Process() 函数的代码:

/// <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();
    }
}

我不确定这是否真的是一种可靠且“专业”的检查端口可用性的方法,但对我来说,这是一个有效且可靠的解决方案。

如果您对如何改进它并使其更不易出错有任何建议和意见,请在文章末尾的评论区写下。

结论

我希望这篇文章对您有所帮助,并希望您能给我一些反馈。

关于**应用程序的奇怪名称**:这是 Harald 和我在开发此应用程序时偶然发现的一个相当有趣的笑话的秘密缩写,您可以肯定我们*绝不会*告诉任何人“dfsmv”真正意味着什么

如果您对某些屏幕截图上的德语感到疑惑:抱歉!我只能有限地访问英文版 Windows,因此一些文本仍是德语;希望您仍然能理解大部分文本。

历史

按升序排列

  • 2003-05-10 初始发布
© . All rights reserved.