Случайное падение соединения с исключением Socket 0x80004005 - PullRequest
2 голосов
/ 13 января 2020

У меня проблема со случайными ошибками crypti c при получении данных с написанного мной TCP-сервера. Исключением является следующее:

System.Net.Sockets.SocketException (0x80004005): An established connection was aborted by the software in your host machine
   at System.Net.Sockets.Socket.BeginReceive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, AsyncCallback callback, Object state)
   at TTS_Simulator.TCPChannel.ReceiveData(IAsyncResult ar)

Я использую асинхронные методы BeginXXX и EndXXX, и другая сторона определенно не закрыла соединение.

Часть кода, отвечающая за принятие соединения :

    protected void AcceptCallback(IAsyncResult ar)
    {
        try
        {
            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);
            _logger.Info("Connection request accepted on local endpoint: " + listener.LocalEndPoint);
            _logger.Info("Connection request accepted from remote endpoint: " + handler.RemoteEndPoint);
            Thread.Sleep(100);

            StateObject state = new StateObject { workSocket = handler };
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                ReceiveData, state);
            IsConnected = true;
            ControlActivator?.Invoke(true);
            listener.BeginAccept(AcceptCallback, listener);
        }
        catch (SocketException ex)
        {
            _logger.Error(ex);
        }
        catch (NullReferenceException ex)
        {
            _logger.Error(ex);
        }
    }

И фрагмент кода, отвечающий за получение сообщений:

    protected void ReceiveData(IAsyncResult ar)
    {
        StateObject state = (StateObject)ar.AsyncState;
        Socket handler = state.workSocket;
        string _inputData = String.Empty;
        int totalBytesRead = 0;
        int bytesRead = 0;

        try
        {
            bytesRead = handler.EndReceive(ar);
            totalBytesRead += bytesRead;

            if (totalBytesRead == 0)
            {
                _logger.Info("Client disconnected at: " + handler.LocalEndPoint);
                handler.Disconnect(true);
                handler.Close();
                handler.Dispose();
                IsConnected = false;
                ControlActivator?.Invoke(false);
                return;
            }

            if (totalBytesRead > 0)
            {
                if (handler.Available > 0)
                {
                    bytesRead = handler.Receive(state.buffer, bytesRead, StateObject.BufferSize,
                        SocketFlags.None);
                    totalBytesRead += bytesRead;
                }
            }
            DataHandler(handler, state.buffer, totalBytesRead);
            totalBytesRead = 0;
            state.workSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, ReceiveData, state);
        }
        catch (System.Net.Sockets.SocketException ex)
        {
            _logger.Error("Error receiving data! \n" + ex);
        }
        catch (Exception ex)
        {
            _logger.Error("Error when processing the data! \n" + ex);
        }
    }

Иногда бывает так, что и сервер, и клиент сообщают об одной и той же проблеме, а иногда это просто либо сервер, либо клиент. Также интересно то, что когда сервер принимает соединение, я вижу в журналах, что на самом деле есть два запроса на соединение, оба принимаются. Не знаю, имеет ли это какое-либо отношение к этому ... Просто примечание: и сервер, и клиент работают на одной машине, которая является виртуальной машиной MS Azure. При необходимости я также могу прикрепить весь код для сервера.

Спасибо!

...