/// <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)); }
/// <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); }