Animatroller.Framework.Expander.Tpm2NetSink.Tpm2NetSink C# (CSharp) Метод

Tpm2NetSink() публичный Метод

public Tpm2NetSink ( [ name = "", int listenPort = 65506 ) : System
name [
listenPort int
Результат System
        public Tpm2NetSink([System.Runtime.CompilerServices.CallerMemberName] string name = "", int listenPort = 65506)
        {
            dataReceived = new Subject<Tpm2BlockData>();

            this.cancelSource = new System.Threading.CancellationTokenSource();

            Task.Run(async () =>
            {
                using (var udpClient = new UdpClient(listenPort))
                {
                    var clientBuffer = new Dictionary<IPEndPoint, InternalBlockData>();

                    while (!this.cancelSource.IsCancellationRequested)
                    {
                        //IPEndPoint object will allow us to read datagrams sent from any source.
                        var receivedResults = await udpClient.ReceiveAsync();

                        InternalBlockData existingData;
                        clientBuffer.TryGetValue(receivedResults.RemoteEndPoint, out existingData);

                        if (existingData == null)
                        {
                            // New block
                            if (receivedResults.Buffer.Length < 5)
                                // Invalid
                                continue;

                            if (receivedResults.Buffer[0] != TPM2net_BlockStart)
                                // No start identifier
                                continue;

                            if (receivedResults.Buffer.Length < 7)
                                // Tpm2Net minimum size is 7 bytes (0 bytes of data, not sure if perhaps it should be minimum 8)
                                continue;

                            BlockTypes blockType;
                            switch (receivedResults.Buffer[1])
                            {
                                case TPM2_BlockType_Data:
                                    blockType = BlockTypes.Data;
                                    break;

                                case TPM2_BlockType_Command:
                                    blockType = BlockTypes.Command;
                                    break;

                                case TPM2_BlockType_Response:
                                    blockType = BlockTypes.Response;
                                    break;

                                default:
                                    // Unknown
                                    continue;
                            }

                            int blockSize = ((int)receivedResults.Buffer[2] << 8) + receivedResults.Buffer[3];

                            existingData = new InternalBlockData
                            {
                                Size = blockSize,
                                Type = blockType,
                                PacketNumber = receivedResults.Buffer[4],
                                TotalPackets = receivedResults.Buffer[5],
                                DataStream = new MemoryStream(blockSize)
                            };

                            int availableBytes = Math.Min(blockSize, receivedResults.Buffer.Length - 7);
                            existingData.DataStream.Write(receivedResults.Buffer, 6, availableBytes);
                        }
                        else
                        {
                            // Continue

                            int availableBytes = Math.Min(existingData.Size, receivedResults.Buffer.Length - 1);
                            existingData.DataStream.Write(receivedResults.Buffer, 0, availableBytes);
                        }

                        if (existingData.DataStream.Length == existingData.Size)
                        {
                            // Completed, check end of block
                            if (receivedResults.Buffer[receivedResults.Buffer.Length - 1] != TPM2_BlockEnd)
                            {
                                // Missing, throw away
                                existingData.Dispose();
                                if (clientBuffer.ContainsKey(receivedResults.RemoteEndPoint))
                                    clientBuffer.Remove(receivedResults.RemoteEndPoint);
                                continue;
                            }

                            // All good
            #if DEBUG_LOG
                            log.Debug("Received block of {0} bytes", existingData.DataStream.Length);
            #endif

                            this.dataReceived.OnNext(new Tpm2BlockData(receivedResults.RemoteEndPoint, existingData));

                            existingData.Dispose();
                        }
                        else
                        {
                            // Not received everything yet
                            if (!clientBuffer.ContainsKey(receivedResults.RemoteEndPoint))
                            {
                                clientBuffer.Add(receivedResults.RemoteEndPoint, existingData);
                            }
                        }
                    }

                    foreach (InternalBlockData blockData in clientBuffer.Values)
                        blockData.Dispose();
                    clientBuffer.Clear();
                }
            });

            Executor.Current.Register(this);
        }