예제 #1
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="agent">Reference to the client this packet is destined for</param>
 /// <param name="buffer">Serialized packet data. If the flags or sequence number
 /// need to be updated, they will be injected directly into this binary buffer</param>
 /// <param name="category">Throttling category for this packet</param>
 /// <param name="type">Packet type</param>
 public OutgoingPacket(LLAgent agent, UDPPacketBuffer buffer, ThrottleCategory category, PacketType type)
 {
     Agent = agent;
     Buffer = buffer;
     Category = category;
     Type = type;
 }
예제 #2
0
파일: UDPBase.cs 프로젝트: jhurliman/simian
        private void AsyncEndReceive(IAsyncResult iar)
        {
            // Asynchronous receive operations will complete here through the call
            // to AsyncBeginReceive
            if (!m_shutdownFlag)
            {
                // Asynchronous mode will start another receive before the
                // callback for this packet is even fired. Very parallel :-)
                if (m_asyncPacketHandling)
                {
                    AsyncBeginReceive();
                }

                // get the buffer that was created in AsyncBeginReceive
                // this is the received data
                //WrappedObject<UDPPacketBuffer> wrappedBuffer = (WrappedObject<UDPPacketBuffer>)iar.AsyncState;
                //UDPPacketBuffer buffer = wrappedBuffer.Instance;
                UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState;

                try
                {
                    // get the length of data actually read from the socket, store it with the
                    // buffer
                    buffer.DataLength = m_udpSocket.EndReceiveFrom(iar, ref buffer.RemoteEndPoint);

                    // call the abstract method PacketReceived(), passing the buffer that
                    // has just been filled from the socket read.
                    PacketReceived(buffer);
                }
                catch (SocketException) { }
                catch (ObjectDisposedException) { }
                finally
                {
                    //wrappedBuffer.Dispose();

                    // Synchronous mode waits until the packet callback completes
                    // before starting the receive to fetch another packet
                    if (!m_asyncPacketHandling)
                    {
                        AsyncBeginReceive();
                    }
                }
            }
        }
예제 #3
0
        private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
        {
            PacketAckPacket ack = new PacketAckPacket();

            ack.Header.Reliable = false;
            ack.Packets         = new PacketAckPacket.PacketsBlock[1];
            ack.Packets[0]      = new PacketAckPacket.PacketsBlock();
            ack.Packets[0].ID   = sequenceNumber;

            byte[] packetData = ack.ToBytes();
            int    length     = packetData.Length;

            UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length);

            buffer.DataLength = length;

            Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);

            Send(buffer);
        }
예제 #4
0
파일: LLUDPServer.cs 프로젝트: thoys/simian
        protected override void PacketReceived(UDPPacketBuffer buffer)
        {
            // Debugging/Profiling
            //try { Thread.CurrentThread.Name = "PacketReceived (" + m_scene.RegionInfo.RegionName + ")"; }
            //catch (Exception) { }

            Packet packet = null;
            int packetEnd = buffer.DataLength - 1;
            IPEndPoint address = (IPEndPoint)buffer.RemoteEndPoint;

            int now = Util.TickCount();

            #region Decoding

            try
            {
                packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
                    // Only allocate a buffer for zerodecoding if the packet is zerocoded
                    ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
            }
            catch (MalformedDataException)
            {
                m_log.ErrorFormat("Malformed data, cannot parse packet from {0}:\n{1}",
                    buffer.RemoteEndPoint, Utils.BytesToHexString(buffer.Data, buffer.DataLength, null));
            }

            // Fail-safe check
            if (packet == null)
            {
                m_log.Warn("Couldn't build a message from incoming data " + buffer.DataLength +
                    " bytes long from " + buffer.RemoteEndPoint);
                return;
            }

            #endregion Decoding

            #region Packet to Client Mapping

            // UseCircuitCode handling
            if (packet.Type == PacketType.UseCircuitCode)
            {
                m_log.Debug("Handling UseCircuitCode packet from " + buffer.RemoteEndPoint);
                HandleUseCircuitCode(buffer, (UseCircuitCodePacket)packet, now);
                return;
            }

            // Determine which agent this packet came from
            LLAgent agent;
            if (!m_clients.TryGetValue(address, out agent))
            {
                m_log.Debug("Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + Scene.Name);
                return;
            }

            if (!agent.IsConnected)
                return;

            #endregion Packet to Client Mapping

            #region Stats Tracking

            Interlocked.Increment(ref m_packetsReceived);
            Interlocked.Increment(ref agent.PacketsReceived);
            agent.TickLastPacketReceived = now;

            if (LoggingEnabled)
                m_log.Debug("--> (" + buffer.RemoteEndPoint + ") " + packet.Type);

            #endregion Stats Tracking

            #region ACK Receiving

            // Handle appended ACKs
            if (packet.Header.AppendedAcks && packet.Header.AckList != null)
            {
                for (int i = 0; i < packet.Header.AckList.Length; i++)
                    agent.NeedAcks.Remove(packet.Header.AckList[i], now, packet.Header.Resent);
            }

            // Handle PacketAck packets
            if (packet.Type == PacketType.PacketAck)
            {
                PacketAckPacket ackPacket = (PacketAckPacket)packet;

                for (int i = 0; i < ackPacket.Packets.Length; i++)
                    agent.NeedAcks.Remove(ackPacket.Packets[i].ID, now, packet.Header.Resent);

                // We don't need to do anything else with PacketAck packets
                return;
            }

            #endregion ACK Receiving

            #region Incoming Packet Accounting

            // Check the archive of received reliable packet IDs to see whether we already received this packet
            if (packet.Header.Reliable && !agent.PacketArchive.TryEnqueue(packet.Header.Sequence))
            {
                if (packet.Header.Resent)
                    m_log.Debug("Received a resend of already processed packet #" + packet.Header.Sequence + ", type: " + packet.Type);
                else
                    m_log.Warn("Received a duplicate (not marked as resend) of packet #" + packet.Header.Sequence + ", type: " + packet.Type);

                // ACK this packet immediately to avoid further resends of this same packet
                SendAckImmediate((IPEndPoint)buffer.RemoteEndPoint, packet.Header.Sequence);

                // Avoid firing a callback twice for the same packet
                return;
            }

            #endregion Incoming Packet Accounting

            #region ACK Sending

            if (packet.Header.Reliable)
            {
                agent.PendingAcks.Enqueue(packet.Header.Sequence);
            }

            #endregion ACK Sending

            #region Ping Check Handling

            if (packet.Type == PacketType.StartPingCheck)
            {
                // We don't need to do anything else with ping checks
                StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
                CompletePing(agent, startPing.PingID.PingID);
                return;
            }
            else if (packet.Type == PacketType.CompletePingCheck)
            {
                // We don't currently track client ping times
                return;
            }

            #endregion Ping Check Handling

            // Inbox insertion
            m_packetInbox.Enqueue(new IncomingPacket(agent, packet, now));
        }
예제 #5
0
파일: LLUDPServer.cs 프로젝트: thoys/simian
        public void SendPacketData(LLAgent agent, byte[] data, PacketType type, ThrottleCategory category)
        {
            int dataLength = data.Length;
            bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0;
            bool doCopy = true;

            // Frequency analysis of outgoing packet sizes shows a large clump of packets at each end of the spectrum.
            // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting
            // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here
            // to accomodate for both common scenarios and provide ample room for ACK appending in both
            int bufferSize = (dataLength > 180)
                ? LLUDPServer.MTU
                : 200;

            UDPPacketBuffer buffer = new UDPPacketBuffer(agent.RemoteEndPoint, bufferSize);

            // Zerocode if needed
            if (doZerocode)
            {
                try
                {
                    dataLength = Helpers.ZeroEncode(data, dataLength, buffer.Data);
                    doCopy = false;
                }
                catch (IndexOutOfRangeException)
                {
                    // The packet grew larger than the bufferSize while zerocoding.
                    // Remove the MSG_ZEROCODED flag and send the unencoded data
                    // instead
                    m_log.Debug("Packet exceeded buffer size during zerocoding for " + type + ". DataLength=" + dataLength +
                        " and BufferLength=" + buffer.Data.Length + ". Removing MSG_ZEROCODED flag");
                    data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED);
                }
            }

            // If the packet data wasn't already copied during zerocoding, copy it now
            if (doCopy)
            {
                if (dataLength > buffer.Data.Length)
                {
                    m_log.Error("Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" +
                        type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length);
                    buffer.Data = new byte[dataLength];
                }

                Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
            }

            buffer.DataLength = dataLength;

            #region Queue or Send

            OutgoingPacket outgoingPacket = new OutgoingPacket(agent, buffer, category, type);

            if (!agent.EnqueueOutgoing(outgoingPacket))
                SendPacketFinal(outgoingPacket);

            #endregion Queue or Send
        }
예제 #6
0
파일: LLUDPServer.cs 프로젝트: thoys/simian
        private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
        {
            PacketAckPacket ack = new PacketAckPacket();
            ack.Header.Reliable = false;
            ack.Packets = new PacketAckPacket.PacketsBlock[1];
            ack.Packets[0] = new PacketAckPacket.PacketsBlock();
            ack.Packets[0].ID = sequenceNumber;

            byte[] packetData = ack.ToBytes();
            int length = packetData.Length;

            UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length);
            buffer.DataLength = length;

            Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);

            Send(buffer);
        }
예제 #7
0
파일: LLUDPServer.cs 프로젝트: thoys/simian
        private void HandleUseCircuitCode(UDPPacketBuffer buffer, UseCircuitCodePacket packet, int now)
        {
            IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;

            LLAgent agent;
            if (m_clients.TryGetValue(packet.CircuitCode.ID, out agent))
            {
                // Update the remoteEndPoint for this agent
                m_clients.UpdateKey2(agent.ID, agent.RemoteEndPoint, remoteEndPoint);
                agent.RemoteEndPoint = remoteEndPoint;

                // Acknowledge the UseCircuitCode packet
                SendAckImmediate(remoteEndPoint, packet.Header.Sequence);

                // Fire any callbacks registered for this packet
                IncomingPacket incomingPacket = new IncomingPacket(agent, packet, now);
                incomingPacket.StartedHandling = now;
                PacketEvents.BeginRaiseEvent(incomingPacket);
            }
            else
            {
                m_log.Error("Failed to add new client " + packet.CircuitCode.ID + " connecting from " + remoteEndPoint);
            }
        }
예제 #8
0
파일: UDPBase.cs 프로젝트: thoys/simian
        public void Send(UDPPacketBuffer buf)
        {
            if (!m_shutdownFlag)
            {
                try
                {
                    m_udpSocket.SendTo(
                        buf.Data,
                        0,
                        buf.DataLength,
                        SocketFlags.None,
                        buf.RemoteEndPoint);

                    //m_udpSocket.BeginSendTo(
                    //    buf.Data,
                    //    0,
                    //    buf.DataLength,
                    //    SocketFlags.None,
                    //    buf.RemoteEndPoint,
                    //    AsyncEndSend,
                    //    buf);
                }
                catch (SocketException) { }
                catch (ObjectDisposedException) { }
            }
        }
예제 #9
0
파일: UDPBase.cs 프로젝트: thoys/simian
        private void AsyncBeginReceive()
        {
            // allocate a packet buffer
            //WrappedObject<UDPPacketBuffer> wrappedBuffer = Pool.CheckOut();
            UDPPacketBuffer buf = new UDPPacketBuffer();

            if (!m_shutdownFlag)
            {
                try
                {
                    // kick off an async read
                    m_udpSocket.BeginReceiveFrom(
                        //wrappedBuffer.Instance.Data,
                        buf.Data,
                        0,
                        UDPPacketBuffer.BUFFER_SIZE,
                        SocketFlags.None,
                        ref buf.RemoteEndPoint,
                        AsyncEndReceive,
                        //wrappedBuffer);
                        buf);
                }
                catch (SocketException e)
                {
                    if (e.SocketErrorCode == SocketError.ConnectionReset)
                    {
                        m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort);
                        bool salvaged = false;
                        while (!salvaged)
                        {
                            try
                            {
                                m_udpSocket.BeginReceiveFrom(
                                    //wrappedBuffer.Instance.Data,
                                    buf.Data,
                                    0,
                                    UDPPacketBuffer.BUFFER_SIZE,
                                    SocketFlags.None,
                                    ref buf.RemoteEndPoint,
                                    AsyncEndReceive,
                                    //wrappedBuffer);
                                    buf);
                                salvaged = true;
                            }
                            catch (SocketException) { }
                            catch (ObjectDisposedException) { return; }
                        }

                        m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort);
                    }
                }
                catch (ObjectDisposedException) { }
            }
        }
예제 #10
0
파일: UDPBase.cs 프로젝트: thoys/simian
 /// <summary>
 /// This method is called when an incoming packet is received
 /// </summary>
 /// <param name="buffer">Incoming packet buffer</param>
 protected abstract void PacketReceived(UDPPacketBuffer buffer);
예제 #11
0
        protected override void PacketReceived(UDPPacketBuffer buffer)
        {
            // Debugging/Profiling
            //try { Thread.CurrentThread.Name = "PacketReceived (" + m_scene.RegionInfo.RegionName + ")"; }
            //catch (Exception) { }

            Packet     packet    = null;
            int        packetEnd = buffer.DataLength - 1;
            IPEndPoint address   = (IPEndPoint)buffer.RemoteEndPoint;

            int now = Util.TickCount();

            #region Decoding

            try
            {
                packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
                                            // Only allocate a buffer for zerodecoding if the packet is zerocoded
                                            ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
            }
            catch (MalformedDataException)
            {
                m_log.ErrorFormat("Malformed data, cannot parse packet from {0}:\n{1}",
                                  buffer.RemoteEndPoint, Utils.BytesToHexString(buffer.Data, buffer.DataLength, null));
            }

            // Fail-safe check
            if (packet == null)
            {
                m_log.Warn("Couldn't build a message from incoming data " + buffer.DataLength +
                           " bytes long from " + buffer.RemoteEndPoint);
                return;
            }

            #endregion Decoding

            #region Packet to Client Mapping

            // UseCircuitCode handling
            if (packet.Type == PacketType.UseCircuitCode)
            {
                m_log.Debug("Handling UseCircuitCode packet from " + buffer.RemoteEndPoint);
                HandleUseCircuitCode(buffer, (UseCircuitCodePacket)packet, now);
                return;
            }

            // Determine which agent this packet came from
            LLAgent agent;
            if (!m_clients.TryGetValue(address, out agent))
            {
                m_log.Debug("Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + Scene.Name);
                return;
            }

            if (!agent.IsConnected)
            {
                return;
            }

            #endregion Packet to Client Mapping

            #region Stats Tracking

            Interlocked.Increment(ref m_packetsReceived);
            Interlocked.Increment(ref agent.PacketsReceived);
            agent.TickLastPacketReceived = now;

            if (LoggingEnabled)
            {
                m_log.Debug("--> (" + buffer.RemoteEndPoint + ") " + packet.Type);
            }

            #endregion Stats Tracking

            #region ACK Receiving

            // Handle appended ACKs
            if (packet.Header.AppendedAcks && packet.Header.AckList != null)
            {
                for (int i = 0; i < packet.Header.AckList.Length; i++)
                {
                    agent.NeedAcks.Remove(packet.Header.AckList[i], now, packet.Header.Resent);
                }
            }

            // Handle PacketAck packets
            if (packet.Type == PacketType.PacketAck)
            {
                PacketAckPacket ackPacket = (PacketAckPacket)packet;

                for (int i = 0; i < ackPacket.Packets.Length; i++)
                {
                    agent.NeedAcks.Remove(ackPacket.Packets[i].ID, now, packet.Header.Resent);
                }

                // We don't need to do anything else with PacketAck packets
                return;
            }

            #endregion ACK Receiving

            #region Incoming Packet Accounting

            // Check the archive of received reliable packet IDs to see whether we already received this packet
            if (packet.Header.Reliable && !agent.PacketArchive.TryEnqueue(packet.Header.Sequence))
            {
                if (packet.Header.Resent)
                {
                    m_log.Debug("Received a resend of already processed packet #" + packet.Header.Sequence + ", type: " + packet.Type);
                }
                else
                {
                    m_log.Warn("Received a duplicate (not marked as resend) of packet #" + packet.Header.Sequence + ", type: " + packet.Type);
                }

                // ACK this packet immediately to avoid further resends of this same packet
                SendAckImmediate((IPEndPoint)buffer.RemoteEndPoint, packet.Header.Sequence);

                // Avoid firing a callback twice for the same packet
                return;
            }

            #endregion Incoming Packet Accounting

            #region ACK Sending

            if (packet.Header.Reliable)
            {
                agent.PendingAcks.Enqueue(packet.Header.Sequence);
            }

            #endregion ACK Sending

            #region Ping Check Handling

            if (packet.Type == PacketType.StartPingCheck)
            {
                // We don't need to do anything else with ping checks
                StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
                CompletePing(agent, startPing.PingID.PingID);
                return;
            }
            else if (packet.Type == PacketType.CompletePingCheck)
            {
                // We don't currently track client ping times
                return;
            }

            #endregion Ping Check Handling

            // Inbox insertion
            m_packetInbox.Enqueue(new IncomingPacket(agent, packet, now));
        }
예제 #12
0
        internal void SendPacketFinal(OutgoingPacket outgoingPacket)
        {
            const int MAX_APPENDED_ACKS = 250;

            UDPPacketBuffer buffer      = outgoingPacket.Buffer;
            byte            flags       = buffer.Data[0];
            bool            isResend    = (flags & Helpers.MSG_RESENT) != 0;
            bool            isReliable  = (flags & Helpers.MSG_RELIABLE) != 0;
            bool            isZerocoded = (flags & Helpers.MSG_ZEROCODED) != 0;
            LLAgent         agent       = outgoingPacket.Agent;

            if (!agent.IsConnected || buffer.RemoteEndPoint == null)
            {
                m_log.Debug("Dropping " + buffer.DataLength + " byte packet to client we have no route to");
                return;
            }

            int dataLength = buffer.DataLength;

            #region ACK Appending

            // NOTE: I'm seeing problems with some viewers when ACKs are appended to zerocoded packets so I've disabled that here
            if (!isZerocoded && outgoingPacket.Type != PacketType.PacketAck)
            {
                // Keep appending ACKs until there is no room left in the buffer or there are
                // no more ACKs to append
                byte ackCount = 0;
                uint ack;
                while (dataLength + 5 < buffer.Data.Length && ackCount < MAX_APPENDED_ACKS && agent.PendingAcks.TryDequeue(out ack))
                {
                    Utils.UIntToBytesBig(ack, buffer.Data, dataLength);
                    dataLength += 4;
                    ++ackCount;
                }

                if (ackCount > 0)
                {
                    // Set the last byte of the packet equal to the number of appended ACKs
                    buffer.Data[dataLength++] = ackCount;
                    // Set the appended ACKs flag on this packet
                    buffer.Data[0] |= Helpers.MSG_APPENDED_ACKS;
                }
            }

            #endregion ACK Appending

            buffer.DataLength = dataLength;

            #region Sequence Number Assignment

            if (!isResend)
            {
                // Not a resend, assign a new sequence number
                uint sequenceNumber = (uint)Interlocked.Increment(ref agent.CurrentSequence);
                Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1);
                outgoingPacket.SequenceNumber = sequenceNumber;

                if (isReliable)
                {
                    // Add this packet to the list of ACK responses we are waiting on from the server
                    agent.NeedAcks.Add(outgoingPacket);
                }
            }

            #endregion Sequence Number Assignment

            // Stats tracking
            Interlocked.Increment(ref agent.PacketsSent);
            Interlocked.Increment(ref m_packetsSent);
            if (isReliable)
            {
                Interlocked.Add(ref agent.UnackedBytes, outgoingPacket.Buffer.DataLength);
            }

            if (LoggingEnabled)
            {
                m_log.Debug("<-- (" + buffer.RemoteEndPoint + ") " + outgoingPacket.Type);
            }

            // Put the UDP payload on the wire
            Send(buffer);

            // Keep track of when this packet was sent out (right now)
            outgoingPacket.TickCount = Util.TickCount();

            //m_log.Debug("Sent " + outgoingPacket.Buffer.DataLength + " byte " + outgoingPacket.Category + " packet");
        }
예제 #13
0
        public void SendPacketData(LLAgent agent, byte[] data, PacketType type, ThrottleCategory category)
        {
            int  dataLength = data.Length;
            bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0;
            bool doCopy     = true;

            // Frequency analysis of outgoing packet sizes shows a large clump of packets at each end of the spectrum.
            // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting
            // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here
            // to accomodate for both common scenarios and provide ample room for ACK appending in both
            int bufferSize = (dataLength > 180)
                ? LLUDPServer.MTU
                : 200;

            UDPPacketBuffer buffer = new UDPPacketBuffer(agent.RemoteEndPoint, bufferSize);

            // Zerocode if needed
            if (doZerocode)
            {
                try
                {
                    dataLength = Helpers.ZeroEncode(data, dataLength, buffer.Data);
                    doCopy     = false;
                }
                catch (IndexOutOfRangeException)
                {
                    // The packet grew larger than the bufferSize while zerocoding.
                    // Remove the MSG_ZEROCODED flag and send the unencoded data
                    // instead
                    m_log.Debug("Packet exceeded buffer size during zerocoding for " + type + ". DataLength=" + dataLength +
                                " and BufferLength=" + buffer.Data.Length + ". Removing MSG_ZEROCODED flag");
                    data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED);
                }
            }

            // If the packet data wasn't already copied during zerocoding, copy it now
            if (doCopy)
            {
                if (dataLength > buffer.Data.Length)
                {
                    m_log.Error("Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" +
                                type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length);
                    buffer.Data = new byte[dataLength];
                }

                Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
            }

            buffer.DataLength = dataLength;

            #region Queue or Send

            OutgoingPacket outgoingPacket = new OutgoingPacket(agent, buffer, category, type);

            if (!agent.EnqueueOutgoing(outgoingPacket))
            {
                SendPacketFinal(outgoingPacket);
            }

            #endregion Queue or Send
        }
예제 #14
0
파일: UDPBase.cs 프로젝트: jhurliman/simian
 /// <summary>
 /// This method is called when an incoming packet is received
 /// </summary>
 /// <param name="buffer">Incoming packet buffer</param>
 protected abstract void PacketReceived(UDPPacketBuffer buffer);