Пример #1
0
        /// <summary>
        /// Send message without connection
        /// </summary>
        /// <param name="message">Raw data</param>
        /// <param name="start">data start</param>
        /// <param name="length">data length</param>
        /// <param name="remoteEndPoint">Packet destination</param>
        /// <returns>Operation result</returns>
        public bool SendUnconnectedMessage(byte[] message, int start, int length, NetEndPoint remoteEndPoint)
        {
            if (!IsRunning)
            {
                return(false);
            }
            var  packet = _netPacketPool.GetWithData(PacketProperty.UnconnectedMessage, message, start, length);
            bool result = SendRawAndRecycle(packet, remoteEndPoint);

            return(result);
        }
Пример #2
0
        private void SendInternal(
            byte[] data,
            int start,
            int length,
            byte channelNumber,
            DeliveryMethod deliveryMethod,
            object userData)
        {
            if (_connectionState == ConnectionState.ShutdownRequested ||
                _connectionState == ConnectionState.Disconnected)
            {
                return;
            }
            if (channelNumber >= _channels.Length)
            {
                return;
            }

            //Select channel
            PacketProperty property;
            BaseChannel    channel;

            if (deliveryMethod == DeliveryMethod.Unreliable)
            {
                property = PacketProperty.Unreliable;
                channel  = _unreliableChannel;
            }
            else
            {
                property = PacketProperty.Channeled;
                channel  = CreateChannel((byte)(channelNumber * 4 + (byte)deliveryMethod));
            }

            //Prepare
            NetDebug.Write("[RS]Packet: " + property);

            //Check fragmentation
            int headerSize = NetPacket.GetHeaderSize(property);
            //Save mtu for multithread
            int mtu = _mtu;

            if (length + headerSize > mtu)
            {
                //if cannot be fragmented
                if (deliveryMethod != DeliveryMethod.ReliableOrdered && deliveryMethod != DeliveryMethod.ReliableUnordered)
                {
                    throw new TooBigPacketException("Unreliable packet size exceeded maximum of " + (_mtu - headerSize) + " bytes");
                }

                int packetFullSize = mtu - headerSize;
                int packetDataSize = packetFullSize - NetConstants.FragmentHeaderSize;
                int totalPackets   = length / packetDataSize + (length % packetDataSize == 0 ? 0 : 1);

                NetDebug.Write("FragmentSend:\n" +
                               " MTU: {0}\n" +
                               " headerSize: {1}\n" +
                               " packetFullSize: {2}\n" +
                               " packetDataSize: {3}\n" +
                               " totalPackets: {4}",
                               mtu, headerSize, packetFullSize, packetDataSize, totalPackets);

                if (totalPackets > ushort.MaxValue)
                {
                    throw new TooBigPacketException("Data was split in " + totalPackets + " fragments, which exceeds " + ushort.MaxValue);
                }

                lock (_sendLock)
                {
                    for (ushort partIdx = 0; partIdx < totalPackets; partIdx++)
                    {
                        int sendLength = length > packetDataSize ? packetDataSize : length;

                        NetPacket p = _packetPool.GetWithProperty(property, sendLength + NetConstants.FragmentHeaderSize);
                        p.UserData       = userData;
                        p.FragmentId     = _fragmentId;
                        p.FragmentPart   = partIdx;
                        p.FragmentsTotal = (ushort)totalPackets;
                        p.MarkFragmented();


                        Buffer.BlockCopy(data, partIdx * packetDataSize, p.RawData, NetConstants.FragmentTotalSize, sendLength);
                        channel.AddToQueue(p);

                        length -= sendLength;
                    }
                    _fragmentId++;
                }
                return;
            }

            //Else just send
            NetPacket packet = _packetPool.GetWithData(property, data, start, length);

            packet.UserData = userData;
            channel.AddToQueue(packet);
        }
Пример #3
0
        /// <summary>
        /// Send data to peer
        /// </summary>
        /// <param name="data">Data</param>
        /// <param name="start">Start of data</param>
        /// <param name="length">Length of data</param>
        /// <param name="options">Send options (reliable, unreliable, etc.)</param>
        public void Send(byte[] data, int start, int length, SendOptions options)
        {
            //Prepare
            PacketProperty property   = SendOptionsToProperty(options);
            int            headerSize = NetPacket.GetHeaderSize(property);

            //Check fragmentation
            if (length + headerSize > _mtu)
            {
                if (options == SendOptions.Sequenced || options == SendOptions.Unreliable)
                {
                    throw new Exception("Unreliable packet size > allowed (" + (_mtu - headerSize) + ")");
                }

                int packetFullSize = _mtu - headerSize;
                int packetDataSize = packetFullSize - NetConstants.FragmentHeaderSize;

                int fullPacketsCount = length / packetDataSize;
                int lastPacketSize   = length % packetDataSize;
                int totalPackets     = fullPacketsCount + (lastPacketSize == 0 ? 0 : 1);

                NetUtils.DebugWrite("FragmentSend:\n" +
                                    " MTU: {0}\n" +
                                    " headerSize: {1}\n" +
                                    " packetFullSize: {2}\n" +
                                    " packetDataSize: {3}\n" +
                                    " fullPacketsCount: {4}\n" +
                                    " lastPacketSize: {5}\n" +
                                    " totalPackets: {6}",
                                    _mtu, headerSize, packetFullSize, packetDataSize, fullPacketsCount, lastPacketSize, totalPackets);

                if (totalPackets > ushort.MaxValue)
                {
                    throw new Exception("Too many fragments: " + totalPackets + " > " + ushort.MaxValue);
                }

                int dataOffset = headerSize + NetConstants.FragmentHeaderSize;
                for (ushort i = 0; i < fullPacketsCount; i++)
                {
                    NetPacket p = _packetPool.Get(property, packetFullSize);
                    p.FragmentId     = _fragmentId;
                    p.FragmentPart   = i;
                    p.FragmentsTotal = (ushort)totalPackets;
                    p.IsFragmented   = true;
                    Buffer.BlockCopy(data, i * packetDataSize, p.RawData, dataOffset, packetDataSize);
                    SendPacket(p);
                }

                if (lastPacketSize > 0)
                {
                    NetPacket p = _packetPool.Get(property, lastPacketSize + NetConstants.FragmentHeaderSize);
                    p.FragmentId     = _fragmentId;
                    p.FragmentPart   = (ushort)fullPacketsCount; //last
                    p.FragmentsTotal = (ushort)totalPackets;
                    p.IsFragmented   = true;
                    Buffer.BlockCopy(data, fullPacketsCount * packetDataSize, p.RawData, dataOffset, lastPacketSize);
                    SendPacket(p);
                }

                _fragmentId++;
                return;
            }

            //Else just send
            NetPacket packet = _packetPool.GetWithData(property, data, start, length);

            SendPacket(packet);
        }
Пример #4
0
        /// <summary>
        /// Send data to peer
        /// </summary>
        /// <param name="data">Data</param>
        /// <param name="start">Start of data</param>
        /// <param name="length">Length of data</param>
        /// <param name="options">Send options (reliable, unreliable, etc.)</param>
        /// <exception cref="TooBigPacketException">
        ///     If size exceeds maximum limit:<para/>
        ///     MTU - headerSize bytes for Unreliable<para/>
        ///     Fragment count exceeded ushort.MaxValue<para/>
        /// </exception>
        public void Send(byte[] data, int start, int length, DeliveryMethod options)
        {
            if (_connectionState == ConnectionState.ShutdownRequested ||
                _connectionState == ConnectionState.Disconnected)
            {
                return;
            }
            //Prepare
            PacketProperty property = SendOptionsToProperty(options);

            NetUtils.DebugWrite("[RS]Packet: " + property);

            //Select channel
            BaseChannel channel;

            switch (property)
            {
            case PacketProperty.ReliableUnordered:
                channel = _reliableUnorderedChannel;
                break;

            case PacketProperty.Sequenced:
                channel = _sequencedChannel;
                break;

            case PacketProperty.ReliableOrdered:
                channel = _reliableOrderedChannel;
                break;

            case PacketProperty.Unreliable:
                channel = _unreliableChannel;
                break;

            case PacketProperty.ReliableSequenced:
                channel = _reliableSequencedChannel;
                break;

            default:
                throw new InvalidPacketException("Unknown packet property: " + property);
            }

            //Check fragmentation
            int headerSize = NetPacket.GetHeaderSize(property);
            //Save mtu for multithread
            int mtu = _mtu;

            if (length + headerSize > mtu)
            {
                if (options == DeliveryMethod.Sequenced ||
                    options == DeliveryMethod.Unreliable ||
                    options == DeliveryMethod.ReliableSequenced)
                {
                    throw new TooBigPacketException("Unreliable packet size exceeded maximum of " + (_mtu - headerSize) + " bytes");
                }

                int packetFullSize = mtu - headerSize;
                int packetDataSize = packetFullSize - NetConstants.FragmentHeaderSize;

                int fullPacketsCount = length / packetDataSize;
                int lastPacketSize   = length % packetDataSize;
                int totalPackets     = fullPacketsCount + (lastPacketSize == 0 ? 0 : 1);

                NetUtils.DebugWrite("FragmentSend:\n" +
                                    " MTU: {0}\n" +
                                    " headerSize: {1}\n" +
                                    " packetFullSize: {2}\n" +
                                    " packetDataSize: {3}\n" +
                                    " fullPacketsCount: {4}\n" +
                                    " lastPacketSize: {5}\n" +
                                    " totalPackets: {6}",
                                    mtu, headerSize, packetFullSize, packetDataSize, fullPacketsCount, lastPacketSize, totalPackets);

                if (totalPackets > ushort.MaxValue)
                {
                    throw new TooBigPacketException("Data was split in " + totalPackets + " fragments, which exceeds " + ushort.MaxValue);
                }

                int dataOffset = headerSize + NetConstants.FragmentHeaderSize;

                lock (_sendLock)
                {
                    for (ushort i = 0; i < fullPacketsCount; i++)
                    {
                        NetPacket p = _packetPool.GetWithProperty(property, packetFullSize);
                        p.FragmentId     = _fragmentId;
                        p.FragmentPart   = i;
                        p.FragmentsTotal = (ushort)totalPackets;
                        p.MarkFragmented();
                        Buffer.BlockCopy(data, i * packetDataSize, p.RawData, dataOffset, packetDataSize);
                        channel.AddToQueue(p);
                    }
                    if (lastPacketSize > 0)
                    {
                        NetPacket p = _packetPool.GetWithProperty(property, lastPacketSize + NetConstants.FragmentHeaderSize);
                        p.FragmentId     = _fragmentId;
                        p.FragmentPart   = (ushort)fullPacketsCount; //last
                        p.FragmentsTotal = (ushort)totalPackets;
                        p.MarkFragmented();
                        Buffer.BlockCopy(data, fullPacketsCount * packetDataSize, p.RawData, dataOffset, lastPacketSize);
                        channel.AddToQueue(p);
                    }
                    _fragmentId++;
                }
                return;
            }

            //Else just send
            NetPacket packet = _packetPool.GetWithData(property, data, start, length);

            channel.AddToQueue(packet);
        }
Пример #5
0
        /// <summary>
        /// Send data to peer
        /// </summary>
        /// <param name="data">Data</param>
        /// <param name="start">Start of data</param>
        /// <param name="length">Length of data</param>
        /// <param name="options">Send options (reliable, unreliable, etc.)</param>
        /// <exception cref="TooBigPacketException">
        ///     If size exceeds maximum limit:<para/>
        ///     MTU - headerSize bytes for Unreliable<para/>
        ///     Fragment count exceeded ushort.MaxValue<para/>
        /// </exception>
        public void Send(byte[] data, int start, int length, DeliveryMethod options)
        {
            if (_connectionState == ConnectionState.ShutdownRequested ||
                _connectionState == ConnectionState.Disconnected)
            {
                return;
            }
            //Prepare
            PacketProperty property   = SendOptionsToProperty(options);
            int            headerSize = NetPacket.GetHeaderSize(property);
            int            mtu        = _mtu;

            //Check fragmentation
            if (length + headerSize > mtu)
            {
                if (options == DeliveryMethod.Sequenced || options == DeliveryMethod.Unreliable)
                {
                    throw new TooBigPacketException("Unreliable packet size exceeded maximum of " + (_mtu - headerSize) + " bytes");
                }

                int packetFullSize = mtu - headerSize;
                int packetDataSize = packetFullSize - NetConstants.FragmentHeaderSize;

                int fullPacketsCount = length / packetDataSize;
                int lastPacketSize   = length % packetDataSize;
                int totalPackets     = fullPacketsCount + (lastPacketSize == 0 ? 0 : 1);

                NetUtils.DebugWrite("FragmentSend:\n" +
                                    " MTU: {0}\n" +
                                    " headerSize: {1}\n" +
                                    " packetFullSize: {2}\n" +
                                    " packetDataSize: {3}\n" +
                                    " fullPacketsCount: {4}\n" +
                                    " lastPacketSize: {5}\n" +
                                    " totalPackets: {6}",
                                    mtu, headerSize, packetFullSize, packetDataSize, fullPacketsCount, lastPacketSize, totalPackets);

                if (totalPackets > ushort.MaxValue)
                {
                    throw new TooBigPacketException("Data was split in " + totalPackets + " fragments, which exceeds " + ushort.MaxValue);
                }

                int dataOffset = headerSize + NetConstants.FragmentHeaderSize;

                lock (_sendLock)
                {
                    for (ushort i = 0; i < fullPacketsCount; i++)
                    {
                        NetPacket p = _packetPool.Get(property, packetFullSize);
                        p.FragmentId     = _fragmentId;
                        p.FragmentPart   = i;
                        p.FragmentsTotal = (ushort)totalPackets;
                        p.IsFragmented   = true;
                        Buffer.BlockCopy(data, i * packetDataSize, p.RawData, dataOffset, packetDataSize);
                        SendPacket(p);
                    }
                    if (lastPacketSize > 0)
                    {
                        NetPacket p = _packetPool.Get(property, lastPacketSize + NetConstants.FragmentHeaderSize);
                        p.FragmentId     = _fragmentId;
                        p.FragmentPart   = (ushort)fullPacketsCount; //last
                        p.FragmentsTotal = (ushort)totalPackets;
                        p.IsFragmented   = true;
                        Buffer.BlockCopy(data, fullPacketsCount * packetDataSize, p.RawData, dataOffset, lastPacketSize);
                        SendPacket(p);
                    }
                    _fragmentId++;
                }
                return;
            }

            //Else just send
            NetPacket packet = _packetPool.GetWithData(property, data, start, length);

            SendPacket(packet);
        }