Как установить время ожидания тестового TCP-соединения? - PullRequest
13 голосов
/ 03 января 2011

Я пытаюсь проверить TCP-соединение с помощью следующего кода.

System.Threading.Thread t = new System.Threading.Thread(() =>
{      
    using (TcpClient client = new TcpClient())
    {
        client.Connect(ip, Convert.ToInt32(port));
    }
});
t.Start();

Как установить тайм-аут, если IP-адрес или порт неверен?

Ответы [ 3 ]

15 голосов
/ 04 января 2011

Нет встроенного способа сделать это. Я использую следующий код для многих наших приложений. Код ни в коем случае не оригинален, но работает хорошо. Обратите внимание, что вам, возможно, придется добавить повторы к этой функции ... иногда она возвращает false, даже когда сервер запущен и работает.

  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 голосов
/ 03 января 2011

Нет прямого способа достичь этого, но один из способов сделать это может быть иметь отдельный метод, который будет проверять соединение.

 static bool TestConnection(string ipAddress, int Port, TimeSpan waitTimeSpan)
        {
            using (TcpClient tcpClient = new TcpClient())
            {
                IAsyncResult result = tcpClient.BeginConnect(ipAddress, Port, null, null);
                WaitHandle timeoutHandler = result.AsyncWaitHandle;
                try
                {
                    if (!result.AsyncWaitHandle.WaitOne(waitTimeSpan, false))
                    {
                        tcpClient.Close();
                        return false;
                    }

                    tcpClient.EndConnect(result);
                }
                catch (Exception ex)
                {
                    return false;
                }
                finally
                {
                    timeoutHandler.Close();
                }
                return true;
            }
        }

Этот метод будет использовать WaitHandle, который будет ожидать в течение указанного периода времени, чтобы установить соединение, если он будет подключен вовремя, он закроет соединение и вернет true, в противном случае он будет тайм-аути вернуть ложь.

8 голосов
/ 13 марта 2015

Слишком поздно, чтобы быть полезным для OP, но для всех, кто еще находит эту страницу из поиска, вы можете решить эту проблему с помощью функций асинхронного программирования, представленных в .Net 4.5.

var hostname = "127.0.0.1";
var port = 123;
var timeout = TimeSpan.FromSeconds(3);
var client = new TcpClient();
if (!client.ConnectAsync(hostname, port).Wait(timeout))
{
    // timed out
}
...