Exemple #1
0
        public void Send(IPEndPoint endPoint, byte[] buffer, int offset, int length, bool reliable)
        {
            var seqState = GetSeqStateOnSend(endPoint);

            if (seqState.DisconnectRequestSent)
            {
                return;
            }

            // Don't send until connected
            if (seqState.SessionId == PacketHeader.EmptySessionId)
            {
                return;
            }

            // Reliable packets should wait for ack before going to pool
            var putBufferToPool = !reliable;

            if (length > MaxPayload - seqState.AckLoad)
            {
                ushort fragId = seqState.NextFragId();
                // Cut packet
                var fragmentCount  = (length + seqState.FullAckLoad + MaxPayload - 1) / MaxPayload;
                var tailSize       = length;
                var fragmentOffset = 0;
                for (int i = 0; i < fragmentCount; ++i)
                {
                    var fragmentSize = Math.Min(MaxPayload - seqState.AckLoad, tailSize);
                    tailSize -= fragmentSize;

                    var fullBuffer = WrapFragment(seqState, buffer, fragmentOffset, fragmentSize, fragId, (ushort)i, (ushort)fragmentCount, reliable);
                    // It should be done after using fragmentOffset to cut fragment
                    fragmentOffset += fragmentSize;

                    try
                    {
                        SubSock.Send(endPoint, fullBuffer.Array, fullBuffer.Offset, fullBuffer.Count, putBufferToPool);
                    }
                    catch (SocketException)
                    {
                        Close(endPoint, seqState);
                        break;
                    }
                }
            }
            else
            {
                var fullBuffer = Wrap(seqState, buffer, offset, length, reliable);
                try
                {
                    SubSock.Send(endPoint, fullBuffer.Array, fullBuffer.Offset, fullBuffer.Count, putBufferToPool);
                }
                catch (SocketException)
                {
                    Close(endPoint, seqState);
                }
            }
        }
Exemple #2
0
        public void Tick(IPEndPoint endPoint, SockBase sock, int now, int ackTimeout, int fragmentTimeout)
        {
            var notAckedCount = _notAcked.Count;

            for (int i = 0; i < notAckedCount; ++i)
            {
                var packet = _notAcked[i];
                if (now - packet.SendTicks > ackTimeout)
                {
                    sock.Send(endPoint, packet.Buffer, packet.Offset, packet.Length, false);
                    packet.SendTicks = now;
                    _notAcked[i]     = packet;
                }
            }

            var packetsCount = _frags.Count;

            for (int i = packetsCount - 1; i >= 0; --i)
            {
                var frag = _frags[i];
                if (SmartSock.TimeDelta(frag.LastActive, now) > fragmentTimeout)
                {
                    _frags.RemoveAt(i);
                    _fragPacketsPool.Put(frag);
                }
            }

            while (_ackQueue.Count > 0)
            {
                var header = _headersPool.Get();
                AddAcks(header);
                header.SetSessionId(SessionId);
                header.Length = (ushort)header.HeaderLength;
                var buffer = _buffersPool.Get(header.Length);
                header.WriteTo(buffer, 0);
                sock.Send(endPoint, buffer, 0, header.Length, true);
                _headersPool.Put(header);
            }
        }