如何设置测试TCP连接超时时间?

13
我尝试使用以下代码测试TCP连接。
System.Threading.Thread t = new System.Threading.Thread(() =>
{      
    using (TcpClient client = new TcpClient())
    {
        client.Connect(ip, Convert.ToInt32(port));
    }
});
t.Start();

如何在IP或端口无效时设置超时?

5
似乎没有一个好的方法来实现它。 - Deniz Dogan
不可能的。超时只能针对发送操作进行调整。当然,您可以实现自己的超时机制,但无法实现更长的超时值。 - Mervin
3个回答

16

没有内置的方法来实现这一点。我在我们的许多应用程序中使用以下代码。代码并不是原创的,但运行得还可以。请注意,有时候即使服务器正在运行,该函数返回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();
        }
    }

1
嗨,我有两个关于代码的问题:1. 未使用的变量success计划用于什么?2. 如果我尝试您的代码示例,在socket.Close()之后我会收到ObjectDisposedException异常。这可能是什么原因? - Offler
变量success没有用处...我只是拿我正在处理的代码部分作为例子。这里的一般思路是,你开始一个异步连接并等待连接成功或超时。然后你检查套接字的连接状态。 - Saibal

11

虽然对于原帖作者来说已经太晚了,但对于其他还在通过搜索找到这个页面的人来说,你可以使用在 .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
}

10

没有直接的方法来实现它,但可以通过编写一个单独的方法来测试连接以实现此目的。

 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,否则,它将超时并返回false。


这种方法并不理想,因为可能会生成连接错误。http://social.msdn.microsoft.com/Forums/en-US/313cf28c-2a6d-498e-8188-7a0639dbd552/tcpclientbeginconnect-issue - Paul Mendoza

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