确定服务器是否正在监听给定端口

6

我需要轮询一个运行了某些专有软件的服务器,以确定该服务是否正在运行。使用wireshark,我已经能够缩小它使用的TCP端口,但似乎流量是加密的。

在我的情况下,如果服务器接受连接(即telnet serverName 1234),那么很有把握该服务已启动,一切正常。换句话说,我不需要进行任何实际数据交换,只需打开一个连接,然后安全地关闭它。

我想知道如何使用C#和Sockets来模拟这种情况。我的网络编程基本上以WebClient结束,所以在这里任何帮助都将不胜感激。

4个回答

10

这个过程实际上非常简单。

using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
    try
    {
        socket.Connect(host, port);
    }
    catch (SocketException ex)
    {
        if (ex.SocketErrorCode == SocketError.ConnectionRefused) 
        {
            // ...
        }
    }
}

有没有办法调整连接超时时间?它似乎会失败,但只有大约一分钟后... - Nate
@Nate 我相信这就是该过程所需的时间。没有连接超时选项。 - ChaosPandion
我添加了 if(ex.SocketErrorCode == SocketError.ConnectionRefused || ex.SocketErrorCode == SocketError.TimedOut) - Nate
虽然看起来很好,也很简单,但我对服务器性能下降有强烈的怀疑。假设它有一个处理程序来处理新客户端的到来(和离开),每当客户端执行这样的检查时,它都会被额外触发。9年后的C#中没有更优雅的方式吗?理想情况下是基于事件的(为此创建事件包装器很容易,但是再次提醒,这将对服务器产生影响)。 - Do-do-new

3

只需使用 TcpClient 尝试连接服务器,如果连接失败,TcpClient.Connect 将抛出异常。

bool IsListening(string server, int port)
{
    using(TcpClient client = new TcpClient())
    {
        try
        {
            client.Connect(server, port);
        }
        catch(SocketException)
        {
            return false;
        }
        client.Close();
        return true;
    }
}

有没有办法调整连接超时时间?似乎会失败,但只有大约一分钟后才出现问题... - Nate

2
我使用了以下代码。但有一个注意事项...在高交易环境下,由于操作系统释放套接字的速度不如.NET代码释放套接字的速度,因此客户端可用端口可能会耗尽。
如果有更好的想法,请发表。我曾看到雪球问题出现,导致服务器无法进行输出连接。我正在研究更好的解决方案...
public static bool IsServerUp(string server, int port, int timeout)
    {
        bool isUp;

        try
        {
            using (TcpClient tcp = new TcpClient())
            {
                IAsyncResult ar = tcp.BeginConnect(server, port, null, null);
                WaitHandle wh = ar.AsyncWaitHandle;

                try
                {
                    if (!wh.WaitOne(TimeSpan.FromMilliseconds(timeout), false))
                    {
                        tcp.EndConnect(ar);
                        tcp.Close();
                        throw new SocketException();
                    }

                    isUp = true;
                    tcp.EndConnect(ar);
                }
                finally
                {
                    wh.Close();
                }
            } 
        }
        catch (SocketException e)
        {
            LOGGER.Warn(string.Format("TCP connection to server {0} failed.", server), e);
            isUp = false;
        }

        return isUp;

0
使用TcpClient类连接服务器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接