public TransmissionResult SendWithoutAck(TcpCommandMessage message) { //Initialization Initialize(message.MessageNumber); //Sending Message try { SimpleSend(message); MessageStatus = TransmissionResult.Successful; return(MessageStatus); } catch (Exception e) { ErrorCause = e; lock (this) { if (hasBeenCancelled) { MessageStatus = TransmissionResult.Cancelled; } else { MessageStatus = TransmissionResult.MessageError; } } CloseSocket(); return(MessageStatus); } }
public TcpCommandMessage GenerateMessage(byte[] message, int bytesReceived) { //<messageNumber-fixed size><CommandCode-fixed size><parameters-fixed size> TcpCommandMessage result; if (bytesReceived < TcpCommandMessage.MESSAGE_NUMBER_LENGTH + commandConverter.LengthInBytes) { throw new FormatException("message length is less than expected"); } byte[] messageNumberInBytes = new byte[TcpCommandMessage.MESSAGE_NUMBER_LENGTH]; byte[] commandInBytes = new byte[commandConverter.LengthInBytes]; byte[] parameters = new byte[bytesReceived - (TcpCommandMessage.MESSAGE_NUMBER_LENGTH + commandConverter.LengthInBytes)]; Array.Copy(message, 0, messageNumberInBytes, 0, messageNumberInBytes.Length); Array.Copy(message, messageNumberInBytes.Length, commandInBytes, 0, commandInBytes.Length); Array.Copy(message, messageNumberInBytes.Length + commandInBytes.Length, parameters, 0, parameters.Length); int messageNumber = ByteArrayConverter.ToInt32(messageNumberInBytes); Command command = commandConverter.GenerateCommand(commandInBytes); result = new TcpCommandMessage(messageNumber, command, parameters); return(result); }
public byte[] GetBytes(TcpCommandMessage message) { if (message.Parameters == null) { message.Parameters = new byte[0]; } byte[] result = new byte[GetMessageLengthInBytes(message)]; int counter; byte[] messageNumberInBytes = ByteArrayConverter.ToArrayOfBytes(message.MessageNumber, TcpCommandMessage.MESSAGE_NUMBER_LENGTH); byte[] commandInBytes = commandConverter.GenerateBytes(message.Command); for (counter = 0; counter < TcpCommandMessage.MESSAGE_NUMBER_LENGTH; counter++) { result[counter] = messageNumberInBytes[counter]; } for (counter = 0; counter < commandConverter.LengthInBytes; counter++) { result[TcpCommandMessage.MESSAGE_NUMBER_LENGTH + counter] = commandInBytes[counter]; } for (counter = 0; counter < message.Parameters.Length; counter++) { result[TcpCommandMessage.MESSAGE_NUMBER_LENGTH + commandConverter.LengthInBytes + counter] = message.Parameters[counter]; } return(result); }
public bool IsAckMessage(TcpCommandMessage message) { if (message.Parameters.Length == 0 && commandConverter.IsAckCommand(message.Command)) { return(true); } else { return(false); } }
//receive a message without a specific number and without specifying a period //and if successful send an ACK //(a mismatching message will result in MessageStatus == TransmissionResult.MessageError) public TransmissionResult ReceiveWithAck(int timeoutInMilliseconds, TcpCommandMessage receivedMessage) { ReceiveWithoutAck(timeoutInMilliseconds, receivedMessage); if (MessageStatus != TransmissionResult.Successful) { return(MessageStatus); } SendAck(); return(MessageStatus); }
/*Public Methods*/ //The timeout is associated with ACK receiving public TransmissionResult SendWithAck(TcpCommandMessage message, int timeoutInMilliseconds) { SendWithoutAck(message); if (MessageStatus != TransmissionResult.Successful) { return(MessageStatus); } Timer ackTimoutTimer = new Timer(new TimerCallback(AckTimedOut), null, timeoutInMilliseconds, Timeout.Infinite); //Receiving ACK ReceiveAck(); ackTimoutTimer.Dispose(); return(MessageStatus); }
//receive a message without a specific number and without specifying a period //(a mismatching message will result in MessageStatus == TransmissionResult.MessageError) public TransmissionResult ReceiveWithoutAck(int timeoutInMilliseconds, TcpCommandMessage receivedMessage) { Initialize(-1); TcpCommandMessage message; int oldTimeout = IOStream.ReadTimeout; IOStream.ReadTimeout = timeoutInMilliseconds; try { message = SimpleReceive(); MessageNumber = message.MessageNumber; IOStream.ReadTimeout = oldTimeout; MessageStatus = TransmissionResult.Successful; message.CopyTo(receivedMessage); return(MessageStatus); } catch (Exception e) { ErrorCause = e; lock (this) { if (hasBeenCancelled) { MessageStatus = TransmissionResult.Cancelled; } else if (IsTimeout(e)) { MessageStatus = TransmissionResult.TimedOut; } else { MessageStatus = TransmissionResult.MessageError; } } CloseSocket(); return(MessageStatus); } }
public void CopyTo(TcpCommandMessage target) { target.MessageNumber = MessageNumber; target.Command = Command; target.Parameters = Parameters; }
protected void SimpleSend(TcpCommandMessage message) { byte[] messageBytes = messageGenerator.GetBytes(message); IOStream.Write(messageBytes, 0, messageBytes.Length); }
public bool IsAckMessage(TcpCommandMessage message, int messageNumber) { return(IsAckMessage(message) && (messageNumber == message.MessageNumber)); }
public int GetMessageLengthInBytes(TcpCommandMessage message) { return(TcpCommandMessage.MESSAGE_NUMBER_LENGTH + commandConverter.LengthInBytes + message.Parameters.Length); }
public TcpCommandMessage GenerateAckMessage(TcpCommandMessage originalMessage) { return(GenerateAckMessage(originalMessage.MessageNumber)); }
//receive a message with a specific number within a timeout period //(within the timeout period mismatching messages will be discarded) public TransmissionResult ReceiveWithoutAck(int expectedMessageNumber, int timeoutInMilliseconds, TcpCommandMessage receivedMessage) { Initialize(expectedMessageNumber); TcpCommandMessage message; Timer ackTimoutTimer = null; try { ackTimoutTimer = new Timer(new TimerCallback(ReceiveTimedOut), null, timeoutInMilliseconds, Timeout.Infinite); message = ReceiveMessageWithCorrectNumber(); MessageStatus = TransmissionResult.Successful; message.CopyTo(receivedMessage); return(MessageStatus); } catch (Exception e) { ErrorCause = e; lock (this) { if (hasBeenCancelled) { MessageStatus = TransmissionResult.Cancelled; } else if (hasTimedOut) { MessageStatus = TransmissionResult.TimedOut; } else { MessageStatus = TransmissionResult.MessageError; } } CloseSocket(); return(MessageStatus); } finally { ackTimoutTimer.Dispose(); } }
//receive a message with a specific number within a timeout period //and if successful executes a method then sens public TransmissionResult ReceiveWithAck(int expectedMessageNumber, int timeoutInMilliseconds, TcpCommandMessage receivedMessage, ToExecuteBeforeSendingACK method, object[] methodParameters) { ReceiveWithoutAck(expectedMessageNumber, timeoutInMilliseconds, receivedMessage); if (MessageStatus != TransmissionResult.Successful) { return(MessageStatus); } method(methodParameters); SendAck(); return(MessageStatus); }