Проверьте соединение с локальным сервером: порт с временем ожидания - PullRequest
2 голосов
/ 22 сентября 2019

Я пытаюсь создать функцию для проверки соединения с сервером: порт, он будет пытаться подключиться к этому серверу: порт каждые 100 мс и возвращать ИСТИНА , если соединение установлено успешно, либо вернуть ЛОЖЬ пока не будет достигнут срок.У меня есть функция, показанная ниже:

private static bool _TryPing(string strIpAddress, int intPort, int nTimeoutMsec)
        {
            Socket socket = null;
            try
            {
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, false);  
                IAsyncResult result = socket.BeginConnect(strIpAddress, intPort, null, null);
                bool success = result.AsyncWaitHandle.WaitOne(nTimeoutMsec, true);

                return socket.Connected;
            }
            catch
            {
                return false;
            }
            finally
            {
                if (null != socket)
                    socket.Close();
            }
        }

Проблема в том, что я использую другое программное обеспечение для создания этого локального сервера: порт, и потребуется 10-20 секунд, чтобы завершить настройку нового порта.Но функция, приведенная выше, проверит при запуске приложения, поэтому оно немедленно вернет false без времени ожидания, поскольку порт еще не открыт.

_TryPing("127.0.0.1", 1080, 20000) //Return FALSE

Может кто-нибудь помочь мне исправить этот код.Спасибо

Ответы [ 2 ]

1 голос
/ 22 сентября 2019

Если порт не открыт, то подключение немедленно прекратится.Если вы хотите подождать некоторое время, чтобы увидеть, открывается ли когда-либо порт, вам нужно повторить попытку подключения в цикле, пока оно не будет успешным или не истечет время ожидания, например:

private static bool hasElapsed(ref Stopwatch sw, int total)
{
    return (sw.ElapsedMilliseconds > (long) total);
}

private static bool hasElapsed(ref Stopwatch sw, int total, out int remaining)
{
    remaining = (int) (((long) total) - sw.ElapsedMilliseconds);
    return (remaining < 0);
}

private static bool _TryPing(string strIpAddress, int intPort, int nTimeoutMsec)
{
    Stopwatch sw = Stopwatch.StartNew();
    do
    {
        try
        {
            using (TcpClient tcp = new TcpClient())
            {
                tcp.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
                IAsyncResult ar = tcp.BeginConnect(strIpAddress, intPort, null, null);
                WaitHandle wh = ar.AsyncWaitHandle;
                try
                {
                    int remaining;
                    if (!hasElapsed(ref sw, nTimeoutMsec, out remaining))
                    {
                        if (wh.WaitOne(remaining))
                        {
                            tcp.EndConnect(ar);
                            return true;
                        }
                    }
                    tcp.Close(); 
                }
                finally
                {
                    wh.Close();
                }
            }
        }
        catch
        {
        }
    }
    while (!hasElapsed(sw, nTimeoutMsec));
    return false;
}
0 голосов
/ 22 сентября 2019

Попробуйте, я не знаю почему, но мне нужно разделить WaitTime на 3, чтобы эта функция работала правильно ...

private static bool TryConnect(string IP, int Port, int WaitTime)
        {
            int RunEvery = 500;
            for (int i = 0; i <= WaitTime/3; i += RunEvery)
            {
                TcpClient client = new TcpClient();
                try
                {
                    client.Connect(IP, Port);
                    Console.WriteLine(IP + ":" + Port + " is active");
                    return true;
                }
                catch(SocketException e)
                {
                    Console.WriteLine("Connection could not be established due to: \n" + e.Message);                    
                    Thread.Sleep(RunEvery);
                }
                finally
                {
                    client.Close();
                }
            }
            return false;
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...