使用c#测试到服务器的连接

本文关键字:连接 服务器 测试 使用 | 更新日期: 2023-09-27 18:29:15

我想测试给定IPEndpoint的服务器是否处于活动状态。我尝试了以下方法,但有时会返回错误的结果。

public bool IsAlive(IPEndPoint ipEndPoint)
{
  if (ipEndPoint == null) return false;
  var tcpClient = new TcpClient();
  var bConnect = tcpClient.BeginConnect(ipEndPoint.Address, ipEndPoint.Port, null, null);
  var isAlive = bConnect.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(1000));
  return isAlive;
}

这种方法错在哪里?

使用c#测试到服务器的连接

仅仅因为AsyncWaitHandle在没有超时的情况下完成,并不意味着它成功地连接了。您需要调用tcpClient.EndConnect(,看看它是否抛出异常,如果没有抛出异常,则一切都好,如果没有,则连接不好。此外,在您的原始方法中,如果您成功连接,则不关闭连接。

如果您使用的是.NET 4.5或更新版本,则很容易实现,请使用ConnectAsync而不是开始/结束对,然后可以使用await

public async Task<bool> IsAliveAsync(IPEndPoint ipEndPoint)
{
  if (ipEndPoint == null) return false;
  using(var tcpClient = new TcpClient())
  {
    var connectTask = tcpClient.ConnectAsync(ipEndPoint.Address, ipEndPoint.Port)
    var timeoutTask = Task.Delay(1000);
    var finishedTask = await Task.WhenAny(connectTask, timeoutTask).ConfigureAwait(false);
    bool isAlive;
    if(finishedTask == timeoutTask)
    {
        isAlive = false;
    }
    else
    {
      try
      {
          await connectTask.ConfigureAwait(false);
          isAlive = true;
      }
      catch
      {
        isAlive = false;
      }
    }
    return isAlive;
  }
}

因为我在await的任何地方都使用.ConfigureAwait(false),所以在从该方法返回的任务上调用.Result应该是安全的,而不是一直在调用堆栈上执行异步/等待。