예제 #1
0
        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);
        }
예제 #6
0
        /*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);
            }
        }
예제 #8
0
 public void CopyTo(TcpCommandMessage target)
 {
     target.MessageNumber = MessageNumber;
     target.Command       = Command;
     target.Parameters    = Parameters;
 }
예제 #9
0
 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);
        }