private void CommunicationLoop() { logger.Verb("CommunicationLoop BEGIN"); try { socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.ReceiveTimeout = 10000; socket.SendTimeout = 10000; logger.Verb($"socket.ConnectAsync(...) {Host} {Port}"); var connectionTask = socket.ConnectAsync(Host, Port); Task.WaitAny(new[] { connectionTask }, 10000); if (!IsSocketConnected()) { throw new Exception("Connection error"); } if (state == ClientState.Connecting) { state = ClientState.Connected; } StateChanged?.Invoke(); while (true) { bool socketConnected = IsSocketConnected(); if (!(socketConnected && state == ClientState.Connected)) { logger.Debug("Connection break " + socketConnected + " " + state); break; } int available = socket.Available; if (available > 0) { IEnumerable <byte[]> dataLines = null; CPSocketHandler socketHanlder = new CPSocketHandler(); Exception exception = null; try { bool bufferProcessed = false; do { byte[] recBuffer = new byte[1024]; int bytesRec = socket.Receive(recBuffer); if (bytesRec > 0) { //The ControlPoint protocol is text-based. Each command line terminates //with CR/LF.Tokens are space separated. All identifiers are case-sensitive. dataLines = socketHanlder.ReadLines(recBuffer, bytesRec); bufferProcessed = (dataLines != null); } else {// socket closed... socketConnected = false; break; } }while (!bufferProcessed); } catch (Exception ex) { logger.Error(ex); exception = ex; } if (dataLines != null) { foreach (var bytes in dataLines) { var cpResponse = CPResponseBase.Create(bytes); var responseType = cpResponse?.ResponseType ?? CPResponseType.Unknown; if (responseType == CPResponseType.Response || cpResponse.ResponseType == CPResponseType.Galileo) { ProcessResponse(cpResponse, exception); } else if (cpResponse.ResponseType == CPResponseType.Notify) { ProcessNotification(cpResponse); } else { ProcessResponse(null, exception); } } dataLines = null; } } socketConnected = IsSocketConnected(); if (!(socketConnected && state == ClientState.Connected)) { logger.Debug("Connection break " + socketConnected + " " + state); break; } { // Response must be received before the next Request is sent! if (sendCommand == null) // обнуляется при получении ответа { if (TryGetCommand(out var command)) { try { var seq = command.seq; var request = (CPRequest)command.request; byte[] sendBuffer = request.GetBytes(); int bytesSent = socket.Send(sendBuffer); sendCommand = command; logger.Debug(">> " + sendCommand.ToString() + "bytesSent: " + bytesSent); } catch (Exception ex) { logger.Error(ex); ProcessResponse(null, ex); } } } } syncEvent.WaitOne(10); } } catch (Exception ex) { logger.Error(ex); } finally { if (socket != null) { if (socket.Connected) { socket.Shutdown(SocketShutdown.Both); } socket.Close(); socket = null; } DrainCommands(); isAuthenticated = false; state = ClientState.Disconnected; StateChanged?.Invoke(); } logger.Verb("CommunicationLoop END"); }