【问题标题】:Check connection to local Server:Port with waiting time检查与本地服务器的连接:等待时间的端口
【发布时间】:2019-09-22 07:50:16
【问题描述】:

我正在尝试创建一个函数来测试与 server:port 的连接,它将尝试每 100 毫秒连接到该 server:port 并返回 TRUE 如果连接成功则返回 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-20 秒才能完成新端口的设置。但是上面的函数会在应用程序启动时检查,所以它会立即返回 false 而无需等待,因为 port 尚未打开。

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

谁能帮我修复这段代码。谢谢

【问题讨论】:

    标签: c# sockets


    【解决方案1】:

    如果端口未打开,则连接将立即失败。如果你想等待一段时间看看端口是否打开,你需要在循环中重试连接,直到连接成功或超时,例如:

    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;
    }
    

    【讨论】:

      【解决方案2】:

      试试这个,我不知道为什么,但我需要将 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;
              }
      

      【讨论】:

      • 我会将for 循环更改为while 循环并继续循环,直到Stopwatch 表示WaitTime 已经过去。此外,您不能对TcpClient.Connect() 使用超时。如果在连接完成之前循环超时,TcpClient.BeginConnect() 将允许取消连接
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      • 2017-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多