2

我面临停止 socket.connect() 函数的问题。有时我的本地机器和远程机器之间的物理链接可能很好,但由于某种原因,无法访问远程端点,可能是防火墙或远程机器上的端口被关闭。在这种情况下,socket.connection() 函数会卡在那里等待无限长的时间……即使以后禁用防火墙,该函数仍然会永远卡在那里。

所以我试图找到一种方法来在遇到上述情况时停止 socket.connect() 。

问题是我正在使用一个 .net 微框架,其中我没有超时机制或任务或 socket.beginconnect();

我正在尝试使 socket.connect() 本身成为一个线程,并尝试在 2 秒后中止它 (!thread.join(2000))。但是,我不太了解 abort() 函数,而且我听说这是一种不明智的做法,而且它毕竟不起作用。

现在我不知道该怎么办?谁能帮忙?多谢

 main function
 {
 m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//Set up socket    
 remoteEndPoint = new IPEndPoint(IPAddress.Parse(IP_add), 30000);
 m_socket.Connect(remoteEndPoint);
 myThread.Start();
        if (!myThread.Join(2000))
         {
          Debug.Print(myThread.ThreadState.ToString());
          myThread.abort();                       
         }
 }

 private static void socket_connect()
    {
        m_socket.Connect(remoteEndPoint);//Connect to remote device  
    }
4

2 回答 2

2

建议Connect通过忙等待来使呼叫超时。我强烈不同意 a) 这种哲学和 b) WinSock 没有提供更好的方法来解决这个常见问题的命题。

这是一个更好的解决方案:

        using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        {
            Task.Factory.StartNew(() =>
                {
                    Thread.Sleep(1000);
                    socket.Close();
                });
            try
            {
                socket.Connect("192.168.2.123", 1234);
            }
            catch (SocketException sex)
            {
                if (sex.ErrorCode == 10038)
                    Console.WriteLine("Timeout");
                else
                    throw;
            }
        }

您自己检测超时并关闭套接字。该程序运行大约需要 1 秒,因此超时机制起作用。

请注意,上面的代码是演示代码,应该使用计时器并且没有竞争。

忙着等待有什么问题?

  • 不好维护
  • 引入延迟
  • 在许多套接字的情况下出现性能问题。在服务器系统上完全无法启动
  • 在客户端上,CPU 无法断电并且您会烧电池
于 2013-02-01T10:57:55.293 回答
0

如果您的框架支持非阻塞连接,您可以尝试此代码。我在 Win7 中为 .net 4 编写了这个。

        Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        Console.WriteLine("Trying to connect");
        socket.Blocking = false;
        try
        {
            socket.Connect("8.8.8.8", 5050);
        }
        catch (Exception ex)
        {
            if (ex is SocketException) && ((SocketException)ex).ErrorCode == 10035) // There is a socket problem and this problem is because of being in non-blocking mode? Then this is just a warning
            {
                // Waiting for connection
                int time = 0;
                while (time < 1000) // If it was lower than 1 second
                {
                    // Do what you want
                    if (socket.Connected) // If connected then break
                        break;
                    System.Threading.Thread.Sleep(50); // Wait 50milisec
                    time += 50;
                }
            }
            else
            {
                Console.WriteLine("Failed");
            }
        }

        if (!socket.Connected)
            Console.WriteLine("Aborted");
        else
            Console.WriteLine("Connected");
于 2013-01-31T22:17:20.233 回答