using System; using System.Collections.Generic; using System.Net; namespace OpenMetaverse { // this class encapsulates a single packet that // is either sent or received by a UDP socket public class UDPPacketBuffer { /// Size of the byte array used to store raw packet data public const int BUFFER_SIZE = 4096; /// Size of the temporary buffer for zerodecoding and /// zeroencoding this packet public const int ZERO_BUFFER_SIZE = 4096; /// Raw packet data buffer public readonly byte[] Data; /// Temporary buffer used for zerodecoding and zeroencoding /// this packet public readonly byte[] ZeroData; /// Length of the data to transmit public int DataLength; /// EndPoint of the remote host public EndPoint RemoteEndPoint; /// /// Create an allocated UDP packet buffer for receiving a packet /// public UDPPacketBuffer() { Data = new byte[UDPPacketBuffer.BUFFER_SIZE]; ZeroData = new byte[UDPPacketBuffer.ZERO_BUFFER_SIZE]; // Will be modified later by BeginReceiveFrom() RemoteEndPoint = (EndPoint)new IPEndPoint(Settings.BIND_ADDR, 0); } /// /// Create an allocated UDP packet buffer for sending a packet /// /// EndPoint of the remote host public UDPPacketBuffer(IPEndPoint endPoint) { Data = new byte[UDPPacketBuffer.BUFFER_SIZE]; ZeroData = new byte[UDPPacketBuffer.ZERO_BUFFER_SIZE]; RemoteEndPoint = (EndPoint)endPoint; } } /// /// Object pool for packet buffers. This is used to allocate memory for all /// incoming and outgoing packets, and zerocoding buffers for those packets /// public class PacketBufferPool : ObjectPoolBase { private IPEndPoint EndPoint; /// /// Initialize the object pool in client mode /// /// Server to connect to /// /// public PacketBufferPool(IPEndPoint endPoint, int itemsPerSegment, int minSegments) : base() { EndPoint = endPoint; Initialize(itemsPerSegment, minSegments, true, 1000 * 60 * 5); } /// /// Initialize the object pool in server mode /// /// /// public PacketBufferPool(int itemsPerSegment, int minSegments) : base() { EndPoint = null; Initialize(itemsPerSegment, minSegments, true, 1000 * 60 * 5); } /// /// Returns a packet buffer with EndPoint set if the buffer is in /// client mode, or with EndPoint set to null in server mode /// /// Initialized UDPPacketBuffer object protected override UDPPacketBuffer GetObjectInstance() { if (EndPoint != null) // Client mode return new UDPPacketBuffer(EndPoint); else // Server mode return new UDPPacketBuffer(); } } public static class Pool { public static PacketBufferPool PoolInstance; /// /// Default constructor /// static Pool() { PoolInstance = new PacketBufferPool(new IPEndPoint(Settings.BIND_ADDR, 0), 16, 1); } /// /// Check a packet buffer out of the pool /// /// A packet buffer object public static WrappedObject CheckOut() { return PoolInstance.CheckOut(); } } }