Example #1
0
 public void ReceiveAndExpectTimeout()
 {
     try
     {
         Console.WriteLine("[{0} {1} millis] ReceiveBlocking, timeout is {2} milliseconds (Expecting TimeoutException)...",
                           name, (Stopwatch.GetTimestamp() - stopwatchStartTicks).StopwatchTicksAsInt64Milliseconds(), timeoutMillis);
         receiveTransmitter.ReceiveBlocking(receiveBuffer, 0, (UInt32)receiveBuffer.Length, timeoutMillis);
         Assert.Fail("Expected TimeoutException");
     }
     catch (TimeoutException)
     {
         Console.WriteLine("[{0} {1} millis] TimeOut Exception", name, (Stopwatch.GetTimestamp() - stopwatchStartTicks).StopwatchTicksAsInt64Milliseconds());
     }
 }
Example #2
0
        public int ReceiveBlocking(byte[] buffer, UInt32 offset, UInt32 maxLength, int timeoutMillis)
        {
            Int64 diffStopwatchTicks = dropReceivedDatagramsUntil - Stopwatch.GetTimestamp();

            if (diffStopwatchTicks > 0)
            {
                Int32 waitTimeMillis = diffStopwatchTicks.StopwatchTicksAsInt32Milliseconds();
                DropAllAvailableDatagrams();

                if (timeoutMillis < waitTimeMillis)
                {
                    Console.WriteLine("[ClumsyTransmitter] Dropping all packets (timeout {0}) drop time {1} is larger than timeout", timeoutMillis, waitTimeMillis);
                    Thread.Sleep(timeoutMillis);
                    DropAllAvailableDatagrams();
                    return(-1);
                }

                if (debugLog != null)
                {
                    debugLog.WriteLine("[ClumsyTransmitter] Sleeping for {0} milliseconds until clumsy transmitter can receive again", waitTimeMillis);
                }
                Thread.Sleep(waitTimeMillis);
                timeoutMillis -= waitTimeMillis;
                Console.WriteLine("[ClumsyTransmitter] Old Timeout {0} New Timeout After Drop {1}", timeoutMillis + waitTimeMillis, timeoutMillis);
            }

            return(underlyingTransmitter.ReceiveBlocking(buffer, offset, maxLength, timeoutMillis));
        }
Example #3
0
        public void ControllerSendPayloadWithAck(UInt32 offsetLimit, ICdpTimeout timeout)
        {
            // 1. Check for acks/resends/halts


            Byte[] bufferToSend = GetRequestedBuffer(offsetLimit);

            try
            {
                // Cdp Header
                UInt32 payloadID = nextPayloadID++;
                bufferToSend[0] = (Byte)(((Byte)CdpFlagValue.PayloadWithAck << 4) |
                                         (0x0F & (payloadID >> 8)));
                bufferToSend[1] = (Byte)payloadID;

                //
                // Send the datagram
                //
                connectedDatagramTransmitter.Send(bufferToSend, 0, offsetLimit);

                Int64 stopwatchTicksAfterSend = Stopwatch.GetTimestamp();

                Int32 timeoutMillis = timeout.WaitForAckInitialRetryTimeout(averageLatency);
                if (timeoutMillis < 0)
                {
                    throw new InvalidOperationException(String.Format(
                                                            "The ICdpTimeout class '{0}' returned negative ({1}) when calling WaitForAckInitialTimeout({2})",
                                                            timeout.GetType().Name, timeoutMillis, averageLatency));
                }

                Int32 retries = 0;

                // Keep resending the datagram until a header is recevied or timeout is reached
                while (true)
                {
                    Console.WriteLine("Send Retry {0}", retries);
                    Int32 bytesRead = connectedDatagramTransmitter.ReceiveBlocking(headerBuffer, 0, 2, timeoutMillis);

                    if (bytesRead < 0)
                    {
                        Int32 elapsedMillis = (Stopwatch.GetTimestamp() - stopwatchTicksAfterSend).StopwatchTicksAsInt32Milliseconds();
                        timeoutMillis = timeout.WaitForAckRetryOrTimeout(retries, averageLatency, elapsedMillis, timeoutMillis);
                        if (timeoutMillis <= 0)
                        {
                            throw new TimeoutException(String.Format("Timed out waiting for ack: {0} retries {1} milliseconds elapsed", retries, elapsedMillis));
                        }

                        // Retry sending the packet
                        connectedDatagramTransmitter.Send(bufferToSend, 0, offsetLimit);
                        retries++;
                        continue;
                    }

                    //
                    // Check the datagram
                    //
                    if (bytesRead == 0)
                    {
                        // It's just a heart beat packet
                    }
                    else
                    {
                        Byte   receivedFlagValue = (Byte)(headerBuffer[0] >> 4);
                        UInt32 receivedPayloadID = (UInt32)((0xF00 & (headerBuffer[0] << 8)) | (0xFF & headerBuffer[1]));
                        if (receivedFlagValue == (Byte)CdpFlagValue.Ack)
                        {
                            if (receivedPayloadID == payloadID)
                            {
                                Console.WriteLine("[CdpDebug] Received ACK for payload id {0}", payloadID);
                                break;
                            }
                            Console.WriteLine("[CdpDebug] Got an ack for an old payload id {0}?", receivedPayloadID);
                        }
                        else if (receivedFlagValue == (Byte)CdpFlagValue.Halt)
                        {
                            throw new CdpBadHaltException();
                        }
                        else if (receivedFlagValue == (Byte)CdpFlagValue.Resend)
                        {
                            if (receivedPayloadID <= payloadID)
                            {
                                UInt32 index = datagramQueue.PayloadIDToIndex(receivedPayloadID);
                                if (index >= 0)
                                {
                                    if (receivedPayloadID < payloadID)
                                    {
                                        do
                                        {
                                            Console.WriteLine("[Debug] Queue Index {0} Payload ID {1}", index, receivedPayloadID + index);
                                            CdpBufferPoolDatagram datagram = datagramQueue.queue[index];
                                            connectedDatagramTransmitter.Send(datagram.datagram, 0, datagram.length);
                                            index++;
                                        } while (receivedPayloadID + index < payloadID);
                                    }
                                    connectedDatagramTransmitter.Send(bufferToSend, 0, offsetLimit);
                                }
                            }
                        }
                        else
                        {
                            Console.WriteLine("Unknown flag value {0} from '{1}' (Maybe I should throw an exception? TBD)",
                                              receivedFlagValue, connectedDatagramTransmitter.RemoteEndPoint);
                        }
                    }

                    //
                    // Get next timeout
                    //
                    {
                        Int32 elapsedMillis = (Stopwatch.GetTimestamp() - stopwatchTicksAfterSend).StopwatchTicksAsInt32Milliseconds();
                        timeoutMillis = timeout.WaitForAckRetryOrTimeout(retries, averageLatency, elapsedMillis, timeoutMillis);
                        if (timeoutMillis <= 0)
                        {
                            throw new TimeoutException(String.Format("Timed out waiting for ack: {0} retries {1} milliseconds elapsed", retries, elapsedMillis));
                        }
                    }
                }

                datagramQueue.EmptyAndFree(); // free the queue because everything has been acked
            }
            finally
            {
                Cdp.BufferPool.FreeBuffer(bufferToSend);
            }
        }