private void ReplySendBase(CommandDefinition.CommandFormat reply) { try { lock (_sessionSocket) { byte[] buffer = reply.Serialize(); if (_sessionSocket.Send(buffer) < 1) throw new Exception(); } } catch { SessionClose( /*_sessionSocket == null*/ ); /*make ServerAgent reconnect*/ throw; } }
private CommandDefinition.CommandFormat? /*reply, if any*/ CommandSend(CommandDefinition.CommandFormat command, bool replyIsExpected = true) { CommandDefinition.CommandFormat? reply = null; try { int ReadBufferLength = 10 * Marshal.SizeOf(typeof(CommandDefinition.CommandFormat)); lock (_commandSendLock) if (/*run?*/ !_monitorEnd.WaitOne(CommandMargin)) if (/*OK?*/ (_connection != null) && _connection.Connected && (_connection.GetStream() != null)) { byte[] buffer = command.Serialize(); _connection.GetStream().Write(buffer, 0, buffer.Length); _connection.GetStream().Flush(); CommandMarginReset(); if (/*reply expected?*/ replyIsExpected) if (/*run?*/ !_monitorEnd.WaitOne(0)) { // Acquire the reply. buffer = new byte[ReadBufferLength]; reply = null; for (int retry = 0; /*OK?*/ retry < CommandSendReads; reply = null, retry++) if (!_connection.GetStream().DataAvailable) if (/*run?*/ !_monitorEnd.WaitOne((retry + 1) * Utilities.TimeTENTH)) continue; else break; else { // Read blocks/waits up through // TcpClient.GetStream().ReadTimeout; if the // client is disposed, the read faults. if (/*read OK?*/ _connection.GetStream().Read(buffer, 0, buffer.Length) >= 1) { reply = CommandSendProcess(command.Deserialize(buffer)); if (/*OK?*/ reply != null) if (/*OK?*/ reply.HasValue) if (/*OK?*/ reply.Value.CommandAck.Command == command.CommandAck.Command) if (/*OK?*/ reply.Value.Action.Action == ActionEnum.Response) { if (/*run?*/ !_monitorEnd.WaitOne(0)) if (/*subscriber(s)?*/ ApcsUpdate != null) try { ApcsUpdate(reply.Value.CommandAck.Command, reply.Value.Action.Action, reply.Value.Action.SubAction, reply.Value.Payload); } catch { } break; } } else break; } try { // Empty the "pipe." buffer = new byte[ReadBufferLength]; Debug.Assert(_connection.GetStream().ReadTimeout == Utilities.TimeTENTH); Debug.Assert(_connection.GetStream().CanRead); while (/*run?*/ !_monitorEnd.WaitOne(0) && /*not empty?*/ _connection.GetStream().DataAvailable) // Read blocks/waits up through // TcpClient.GetStream().ReadTimeout; if the // client is disposed, the read faults. if (/*data?*/ _connection.GetStream().Read(buffer, 0, buffer.Length) >= 1) CommandSendProcess(command.Deserialize(buffer)); } catch { } } } } catch { ConnectionDispose(); if (/*run?*/ !_monitorEnd.WaitOne(0)) throw; } return reply; }
private CommandDefinition.CommandFormat? SendCommand(CommandDefinition.CommandFormat command, bool expectingReply) { CommandDefinition.CommandFormat? response = null; try { if (Connected) { byte[] cmd = command.Serialize(); _responseEvent.Reset(); _networkStream.Write(cmd, 0, cmd.Length); for (int i = 0; i < _sendCommandRetrys; i++) { if (_responseEvent.WaitOne(_apcsCommandTimeout)) { if (_commandResponse.CommandAck.Command == command.CommandAck.Command && _commandResponse.Action.Action == ActionEnum.Response) { response = _commandResponse; _responseEvent.Reset(); break; } } } } #if false else throw new Exception("SendCommand called while not connected to APCS."); #endif } catch (Exception ex) { if (/*not terminated?*/ !_cancelEvent.WaitOne(0)) { Debug.Assert(Lgr != null); Lgr.LogError(ex); } } return response; }