Как остановить функцию socket.connect(), если она зависает?

Я сталкиваюсь с проблемой остановки функции 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  
    }

2 ответа

Было предложено иметь Connect тайм-аут вызова занятым ожиданием. Я категорически не согласен с а) этой философией и б) утверждением, что 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 секунды, чтобы сработал механизм тайм-аута.

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

Что плохого в занятом ожидании?

  • Плохо поддерживать
  • Вводит задержку
  • Perf-проблема в случае множества сокетов. Полностью не стартер на серверных системах
  • На клиентах ЦП не может выключиться, и вы сжигаете батарею

Если ваша платформа поддерживает неблокирующие соединения, вы можете попробовать этот код. Я написал это для.net 4 в Win7.

        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");
Другие вопросы по тегам