예제 #1
0
        /// <summary>
        /// filter the disconnected event from specified client.
        /// </summary>
        /// <param name="obj">
        /// a UdpReceivedBytes object that contains the event to filt.
        /// </param>
        /// <returns>
        /// if the received data is from the specified local endpoint, return true; otherwise, false.
        /// </returns>
        public bool FilterUdpPacketOrBytes(IPEndPointStackPacket obj)
        {
            if (obj == null)
            {
                return(false);
            }

            return(this.CompareUdpPacketOrBytes(obj.LocalEndPoint));
        }
        /// <summary>
        /// get packet from packet cache or decode from buffer.
        /// </summary>
        /// <param name="timeout">
        /// a TimeSpan object that specifies the timeout
        /// </param>
        /// <param name="removeEvent">
        /// a bool value that indicates whether need to remove the event from buffer.
        /// </param>
        /// <param name="remoteEndPoint">
        /// an object that specifies the remote endpoint.
        /// </param>
        /// <returns>
        /// a StackPacket object that contains the decoded packet.
        /// </returns>
        private StackPacket GetPacket(TimeSpan timeout, bool removeEvent, out object remoteEndPoint)
        {
            // get the packet in packet list.
            IPEndPointStackPacket packet = Utility.GetOne <IPEndPointStackPacket>(this.packetCache, null);

            if (packet != null)
            {
                remoteEndPoint = packet.RemoteEndPoint;

                return(packet.Packet);
            }

            UdpReceivedBytes bytes = this.buffer.Dequeue(timeout);

            remoteEndPoint = bytes.RemoteEndPoint;

            // exception event arrived
            if (bytes.Packet == null)
            {
                if (!removeEvent)
                {
                    this.buffer.Enqueue(bytes);
                }

                InvalidOperationException exc =
                    new InvalidOperationException("exception arrived when expect packet from udp.");

                // identify this exception.
                exc.Data.Add(exc.GetType().Name, true);

                throw exc;
            }

            // decode packets using data in buffer.
            int consumedLength = 0;
            int expectedLength = 0;

            StackPacket[] packets = this.decoder(remoteEndPoint, bytes.Packet, out consumedLength, out expectedLength);

            // if no packet, drop the recieved data and continue.
            if (packets == null || packets.Length == 0)
            {
                throw new InvalidOperationException("udp client failed to decode udp packet");
            }

            // if packet arrived, add to packet list, and return the first.
            foreach (StackPacket item in packets)
            {
                this.packetCache.Enqueue(
                    new IPEndPointStackPacket(item, bytes.RemoteEndPoint, bytes.LocalEndPoint));
            }

            // set timeout to zero. when packet is decoded, must not wait.
            return(GetPacket(new TimeSpan(), removeEvent, out remoteEndPoint));
        }
        /// <summary>
        /// expect packet from transport.<para/>
        /// the transport must be a TcpServer, UdpClient or UdpServer.
        /// </summary>
        /// <param name="endpoint">
        /// an IPEndPoint object that specifies the endpoint to get packet.
        /// </param>
        /// <param name="timeout">
        /// a TimeSpan object that indicates the timeout to expect event.
        /// </param>
        /// <param name="removeEvent">
        /// a bool value that indicates whether need to remove the event from buffer.
        /// </param>
        /// <param name="remoteEndPoint">
        /// an object that specifies the remote endpoint expected packet.
        /// </param>
        /// <param name="localEndPoint">
        /// an object that indicates the local endpoint received packet at.
        /// </param>
        /// <returns>
        /// a StackPacket object that specifies the received packet.<para/>
        /// never return null, if no packets, throw exception.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        /// thrown when udp server failed to decode udp packet
        /// </exception>
        private StackPacket GetFilteredPacket(
            IPEndPoint endpoint, TimeSpan timeout, bool removeEvent,
            out object remoteEndPoint, out object localEndPoint)
        {
            // generate the filter.
            Filter <IPEndPointStackPacket> packetFilter = null;
            Filter <UdpReceivedBytes>      bytesFilter  = null;

            if (endpoint != null)
            {
                packetFilter = new TransportFilter(endpoint).FilterUdpPacketOrBytes;
                bytesFilter  = new TransportFilter(endpoint).FilterUdpPacketOrBytes;
            }

            // get the packet in packet list.
            IPEndPointStackPacket packet = Utility.GetOne <IPEndPointStackPacket>(this.packetCache, packetFilter);

            if (packet != null)
            {
                remoteEndPoint = packet.RemoteEndPoint;
                localEndPoint  = packet.LocalEndPoint;

                return(packet.Packet);
            }

            UdpReceivedBytes bytes = this.GetUdpBytes(
                bytesFilter, timeout, removeEvent, out remoteEndPoint, out localEndPoint);

            // decode packets using data in buffer.
            int consumedLength = 0;
            int expectedLength = 0;

            StackPacket[] packets = this.decoder(remoteEndPoint, bytes.Packet, out consumedLength, out expectedLength);

            // if no packet, drop the recieved data and continue.
            if (packets == null || packets.Length == 0)
            {
                throw new InvalidOperationException("udp server failed to decode udp packet");
            }

            // if packet arrived, add to packet list, and return the first.
            foreach (StackPacket item in packets)
            {
                this.packetCache.Enqueue(
                    new IPEndPointStackPacket(item, bytes.RemoteEndPoint, bytes.LocalEndPoint));
            }

            // set timeout to zero. when packet is decoded, must not wait.
            return(GetFilteredPacket(endpoint, new TimeSpan(), removeEvent, out remoteEndPoint, out localEndPoint));
        }
예제 #4
0
        /// <summary>
        /// filter the disconnected event from specified client.
        /// </summary>
        /// <param name="obj">
        /// a UdpReceivedBytes object that contains the event to filt.
        /// </param>
        /// <returns>
        /// if the received data is from the specified local endpoint, return true; otherwise, false.
        /// </returns>
        public bool FilterIPEndPoint(IPEndPointStackPacket obj)
        {
            if (obj == null)
            {
                return(false);
            }

            // compare the endpoint.
            if (obj.RemoteEndPoint == null || !obj.RemoteEndPoint.Equals(this.endpoint))
            {
                return(false);
            }

            return(true);
        }