Exemplo n.º 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, 0, message, start, length);
            bool result = SendRawAndRecycle(packet, remoteEndPoint);

            return(result);
        }
Exemplo n.º 2
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>
        /// <param name="channel">Set the channel wanted. See NetConstants.MultiChannelSize</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, int channel)
        {
            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 - NetPacket.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 = 0;

                lock (_sendLock)
                {
                    for (ushort i = 0; i < fullPacketsCount; i++)
                    {
                        NetPacket p = _packetPool.Get(property, channel, 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, channel, lastPacketSize + NetPacket.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, channel, data, start, length);

            SendPacket(packet);
        }