Ejemplo n.º 1
0
        /// <summary>
        /// Releases expired streams.
        /// </summary>
        public void TimerCallback()
        {
            int now          = GenuineUtility.TickCount;
            int releaseAfter = GenuineUtility.ConvertToMilliseconds(this.ITransportContext.IParameterProvider[GenuineParameter.UdpAssembleTimeSpan]);

            lock (this._streams.SyncRoot)
            {
                // gather expired stream
                ArrayList itemsDeleted = new ArrayList();
                foreach (DictionaryEntry entry in this._streams)
                {
                    StreamAssembled streamAssembled = (StreamAssembled)entry.Value;
                    if (GenuineUtility.IsTimeoutExpired(streamAssembled.Started + releaseAfter, now) &&
                        !streamAssembled.IsProcessed)
                    {
                        itemsDeleted.Add(entry.Key);
                        streamAssembled.Close();
                    }
                }

                // and remove them
                foreach (object key in itemsDeleted)
                {
                    this._streams.Remove(key);
                }
            }
        }
        /// <summary>
        /// Receives the content synchronously.
        /// </summary>
        private void ReceiveSynchronously()
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
            byte[] receiveBuffer = null;
            this._receivingThreadClosed.Reset();

            try
            {
                int mtu = (int) this.ITransportContext.IParameterProvider[GenuineParameter.UdpMtu];
                for ( ; ; )
                {
                    if (this._closing)
                        return ;

                    if (BufferPool.GENERAL_BUFFER_SIZE >= mtu)
                        receiveBuffer = BufferPool.ObtainBuffer();
                    else
                        receiveBuffer = new byte[mtu];

                    try
                    {
                        IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 0);
                        EndPoint endPointReference = ipEndPoint;
                        int bytesReceived = this._socket.ReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, ref endPointReference);
                        ipEndPoint = (IPEndPoint) endPointReference;

                        // LOG:
                        if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Transport] > 0 )
                        {
                            binaryLogWriter.WriteTransportContentEvent(LogCategory.Transport, "UdpConnectionManager.ReceiveSynchronously",
                                LogMessageType.ReceivingFinished, null, null, null,
                                binaryLogWriter[LogCategory.Transport] > 1 ? new MemoryStream(GenuineUtility.CutOutBuffer(receiveBuffer, 0, bytesReceived)) : null,
                                GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                this.DbgConnectionId, bytesReceived, ipEndPoint.ToString(),
                                null, null,
                                "Content is received from {0}.", ipEndPoint.ToString());
                        }

                        // parse the header
                        if (bytesReceived < HEADER_SIZE)
                            throw GenuineExceptions.Get_Receive_IncorrectData();
                        if (receiveBuffer[0] != MessageCoder.COMMAND_MAGIC_CODE)
                            throw GenuineExceptions.Get_Receive_IncorrectData();

                        // get the packet identifier
                        byte[] guidBuffer = new byte[16];
                        Buffer.BlockCopy(receiveBuffer, 1, guidBuffer, 0, 16);
                        Guid packetGuid = new Guid(guidBuffer);

                        // and chunk number
                        int chunkNumber = MessageCoder.ReadInt32(receiveBuffer, 17);
                        bool isLast = chunkNumber < 0;
                        if (chunkNumber < 0)
                            chunkNumber = - chunkNumber;
                        chunkNumber --;

                        // process the chunk
                        StreamAssembled streamAssembled;
                        lock (this._streams.SyncRoot)
                        {
                            streamAssembled = this._streams[packetGuid] as StreamAssembled;
                            if (streamAssembled == null)
                                this._streams[packetGuid] = streamAssembled = new StreamAssembled(ipEndPoint, HEADER_SIZE);
                            if (streamAssembled.IsProcessed)
                                continue;
                        }

                        string uri = "gudp://" + ipEndPoint.ToString();
                        HostInformation remote = this.ITransportContext.KnownHosts[uri];
                        remote.Renew(this._closeInvocationConnectionAfterInactivity, false);

                        if ((int) this.ITransportContext.IParameterProvider[GenuineParameter.CompatibilityLevel] <= 0)
                            remote.UpdateUri(uri, 0, false);

                        if (streamAssembled.BufferReceived(chunkNumber, receiveBuffer, bytesReceived, isLast))
                        {
                            // prepare it for processing
                            this._streams.Remove(packetGuid);
                            streamAssembled.IsProcessed = true;

                            // read the remote host URI
                            if ((int) this.ITransportContext.IParameterProvider[GenuineParameter.CompatibilityLevel] > 0)
                            {
                                BinaryReader binaryReader = new BinaryReader(streamAssembled);

                                // read the URI
                                byte[] uriBuffer = new byte[16];
                                GenuineUtility.ReadDataFromStream(streamAssembled, uriBuffer, 0, uriBuffer.Length);
                                Guid remoteHostUriGuid = new Guid(uriBuffer);
                                string receivedUri = "_gudp://" + remoteHostUriGuid.ToString("N");

                                // read the remote host unique identifier
                                int remoteHostUniqueIdentifier = binaryReader.ReadInt32();

                                // update the host information
                                remote.UpdateUri(receivedUri, remoteHostUniqueIdentifier, false);

                                // and skip the skip space
                                GenuineUtility.CopyStreamToStream(streamAssembled, Stream.Null, binaryReader.ReadInt16());
                            }

                            // LOG:
                            if ( remote.PhysicalAddress == null && binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0 )
                            {
                                binaryLogWriter.WriteHostInformationEvent("UdpConnectionManager.ReceiveSynchronously",
                                    LogMessageType.HostInformationCreated, null, remote,
                                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                    null, null,
                                    this.DbgConnectionId,
                                    "HostInformation is ready for actions.");
                            }

                            remote.PhysicalAddress = endPointReference;
                            this.ITransportContext.IIncomingStreamHandler.HandleMessage(streamAssembled, remote, GenuineConnectionType.Persistent, string.Empty, -1, false, this._iMessageRegistrator, null, null);
                        }
                    }
                    catch(Exception ex)
                    {
                        // LOG:
                        if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                        {
                            binaryLogWriter.WriteEvent(LogCategory.Connection, "UdpConnectionManager.ReceiveSynchronously",
                                LogMessageType.ReceivingFinished, ex, null, null, null,
                                GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                null, null,
                                this.DbgConnectionId, 0, 0, 0, null, null, null, null,
                                "UDP socket failure.");
                        }

                        if (this._closing)
                            return ;

                        this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GUdpSocketException, ex, this.Local, null));
                    }
                }
            }
            finally
            {
                this._receivingThreadClosed.Set();
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Receives the content synchronously.
        /// </summary>
        private void ReceiveSynchronously()
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            byte[] receiveBuffer = null;
            this._receivingThreadClosed.Reset();

            try
            {
                int mtu = (int)this.ITransportContext.IParameterProvider[GenuineParameter.UdpMtu];
                for ( ; ;)
                {
                    if (this._closing)
                    {
                        return;
                    }

                    if (BufferPool.GENERAL_BUFFER_SIZE >= mtu)
                    {
                        receiveBuffer = BufferPool.ObtainBuffer();
                    }
                    else
                    {
                        receiveBuffer = new byte[mtu];
                    }

                    try
                    {
                        IPEndPoint ipEndPoint        = new IPEndPoint(IPAddress.Any, 0);
                        EndPoint   endPointReference = ipEndPoint;
                        int        bytesReceived     = this._socket.ReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, ref endPointReference);
                        ipEndPoint = (IPEndPoint)endPointReference;

                        // LOG:
                        if (binaryLogWriter != null && binaryLogWriter[LogCategory.Transport] > 0)
                        {
                            binaryLogWriter.WriteTransportContentEvent(LogCategory.Transport, "UdpConnectionManager.ReceiveSynchronously",
                                                                       LogMessageType.ReceivingFinished, null, null, null,
                                                                       binaryLogWriter[LogCategory.Transport] > 1 ? new MemoryStream(GenuineUtility.CutOutBuffer(receiveBuffer, 0, bytesReceived)) : null,
                                                                       GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                                       this.DbgConnectionId, bytesReceived, ipEndPoint.ToString(),
                                                                       null, null,
                                                                       "Content is received from {0}.", ipEndPoint.ToString());
                        }

                        // parse the header
                        if (bytesReceived < HEADER_SIZE)
                        {
                            throw GenuineExceptions.Get_Receive_IncorrectData();
                        }
                        if (receiveBuffer[0] != MessageCoder.COMMAND_MAGIC_CODE)
                        {
                            throw GenuineExceptions.Get_Receive_IncorrectData();
                        }

                        // get the packet identifier
                        byte[] guidBuffer = new byte[16];
                        Buffer.BlockCopy(receiveBuffer, 1, guidBuffer, 0, 16);
                        Guid packetGuid = new Guid(guidBuffer);

                        // and chunk number
                        int  chunkNumber = MessageCoder.ReadInt32(receiveBuffer, 17);
                        bool isLast      = chunkNumber < 0;
                        if (chunkNumber < 0)
                        {
                            chunkNumber = -chunkNumber;
                        }
                        chunkNumber--;

                        // process the chunk
                        StreamAssembled streamAssembled;
                        lock (this._streams.SyncRoot)
                        {
                            streamAssembled = this._streams[packetGuid] as StreamAssembled;
                            if (streamAssembled == null)
                            {
                                this._streams[packetGuid] = streamAssembled = new StreamAssembled(ipEndPoint, HEADER_SIZE);
                            }
                            if (streamAssembled.IsProcessed)
                            {
                                continue;
                            }
                        }

                        string          uri    = "gudp://" + ipEndPoint.ToString();
                        HostInformation remote = this.ITransportContext.KnownHosts[uri];
                        remote.Renew(this._closeInvocationConnectionAfterInactivity, false);

                        if ((int)this.ITransportContext.IParameterProvider[GenuineParameter.CompatibilityLevel] <= 0)
                        {
                            remote.UpdateUri(uri, 0, false);
                        }

                        if (streamAssembled.BufferReceived(chunkNumber, receiveBuffer, bytesReceived, isLast))
                        {
                            // prepare it for processing
                            this._streams.Remove(packetGuid);
                            streamAssembled.IsProcessed = true;

                            // read the remote host URI
                            if ((int)this.ITransportContext.IParameterProvider[GenuineParameter.CompatibilityLevel] > 0)
                            {
                                BinaryReader binaryReader = new BinaryReader(streamAssembled);

                                // read the URI
                                byte[] uriBuffer = new byte[16];
                                GenuineUtility.ReadDataFromStream(streamAssembled, uriBuffer, 0, uriBuffer.Length);
                                Guid   remoteHostUriGuid = new Guid(uriBuffer);
                                string receivedUri       = "_gudp://" + remoteHostUriGuid.ToString("N");

                                // read the remote host unique identifier
                                int remoteHostUniqueIdentifier = binaryReader.ReadInt32();

                                // update the host information
                                remote.UpdateUri(receivedUri, remoteHostUniqueIdentifier, false);

                                // and skip the skip space
                                GenuineUtility.CopyStreamToStream(streamAssembled, Stream.Null, binaryReader.ReadInt16());
                            }

                            // LOG:
                            if (remote.PhysicalAddress == null && binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0)
                            {
                                binaryLogWriter.WriteHostInformationEvent("UdpConnectionManager.ReceiveSynchronously",
                                                                          LogMessageType.HostInformationCreated, null, remote,
                                                                          GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                                          null, null,
                                                                          this.DbgConnectionId,
                                                                          "HostInformation is ready for actions.");
                            }

                            remote.PhysicalAddress = endPointReference;
                            this.ITransportContext.IIncomingStreamHandler.HandleMessage(streamAssembled, remote, GenuineConnectionType.Persistent, string.Empty, -1, false, this._iMessageRegistrator, null, null);
                        }
                    }
                    catch (Exception ex)
                    {
                        // LOG:
                        if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0)
                        {
                            binaryLogWriter.WriteEvent(LogCategory.Connection, "UdpConnectionManager.ReceiveSynchronously",
                                                       LogMessageType.ReceivingFinished, ex, null, null, null,
                                                       GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                       null, null,
                                                       this.DbgConnectionId, 0, 0, 0, null, null, null, null,
                                                       "UDP socket failure.");
                        }

                        if (this._closing)
                        {
                            return;
                        }

                        this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GUdpSocketException, ex, this.Local, null));
                    }
                }
            }
            finally
            {
                this._receivingThreadClosed.Set();
            }
        }