コード例 #1
0
        public bool Receive(ref ReceivedSmartPacket receivedPacket)
        {
            bool haveResult = false;
            var  packet     = new ReceivedPacket();

            while (true)
            {
                if (SubSock.Receive(ref packet))
                {
                    try
                    {
                        haveResult = OnReceive(packet.Buffer, packet.Offset, packet.Length, packet.EndPoint,
                                               ref receivedPacket);
                    }
                    catch (Exception)
                    {
                        haveResult = false;
                        _buffersPool.Put(packet.Buffer);
                    }
                }
                else
                {
                    break;
                }

                if (haveResult)
                {
                    break;
                }
            }

            return(haveResult);
        }
コード例 #2
0
 public bool Receive(ref ReceivedSmartPacket receivedPacket)
 {
     lock (_syncObject)
     {
         return(_socket.Receive(ref receivedPacket));
     }
 }
コード例 #3
0
        public bool Receive(ref ReceivedSmartPacket receivedPacket)
        {
            if (_recvQueue.Count > 0)
            {
                receivedPacket = _recvQueue.Take();
                return(true);
            }

            return(false);
        }
コード例 #4
0
        private void IOLoop()
        {
            bool active = false;

            while (!_closing)
            {
                lock (_syncObject)
                {
                    _socket.Tick();
                }

                SmartPacketToSend packetToSend = new SmartPacketToSend();
                if (_sendQueue.Count > 0)
                {
                    active = true;

                    packetToSend = _sendQueue.Take();
                    lock (_syncObject)
                    {
                        _socket.Send(packetToSend.EndPoint, packetToSend.Buffer, packetToSend.Offset, packetToSend.Length, packetToSend.Reliable);
                    }
                    if (packetToSend.PutBufferToPool)
                    {
                        _buffersPool.Put(packetToSend.Buffer);
                    }
                }

                ReceivedSmartPacket receivedPacket = new ReceivedSmartPacket();
                bool received;
                lock (_syncObject)
                {
                    received = _socket.Receive(ref receivedPacket);
                }
                if (received)
                {
                    active = true;

                    _recvQueue.Add(receivedPacket);
                }

                if (!active)
                {
                    Thread.Sleep(10);
                }
            }
        }
コード例 #5
0
        private void IOLoop()
        {
            while (!_closing)
            {
                try
                {
                    bool active = false;

                    _socket.Tick();
                    State = _socket.State;

                    SmartPacketToSend packetToSend = new SmartPacketToSend();
                    if (_sendQueue.Count > 0)
                    {
                        active = true;

                        packetToSend = _sendQueue.Take();
                        _socket.Send(packetToSend.EndPoint, packetToSend.Buffer, packetToSend.Offset, packetToSend.Length, packetToSend.Reliable);
                        if (packetToSend.PutBufferToPool)
                        {
                            _buffersPool.Put(packetToSend.Buffer);
                        }
                    }

                    ReceivedSmartPacket receivedPacket = new ReceivedSmartPacket();
                    if (_socket.Receive(ref receivedPacket))
                    {
                        active = true;

                        _recvQueue.Add(receivedPacket);
                    }

                    if (!active)
                    {
                        Thread.Sleep(10);
                    }
                }
                catch (Exception)
                {
                    _closing = true;
                }
            }

            _socket.Close();
            State = PixocketState.NotConnected;
        }
コード例 #6
0
ファイル: SmartSock.cs プロジェクト: pixonic/pixockets
        public bool Receive(ref ReceivedSmartPacket receivedPacket)
        {
            bool haveResult = false;
            var  packet     = new ReceivedPacket();

            while (true)
            {
                try
                {
                    packet.EndPoint = null;
                    if (SubSock.Receive(ref packet))
                    {
                        try
                        {
                            haveResult = OnReceive(packet.Buffer, packet.Offset, packet.Length, packet.EndPoint,
                                                   ref receivedPacket);
                        }
                        catch (SocketException)
                        {
                            haveResult = false;
                            _buffersPool.Put(packet.Buffer);
                            if (packet.EndPoint != null && _seqStates.ContainsKey(packet.EndPoint))
                            {
                                Close(packet.EndPoint, _seqStates[packet.EndPoint]);
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                catch (SocketException)
                {
                    Close();
                }

                if (haveResult)
                {
                    break;
                }
            }

            return(haveResult);
        }
コード例 #7
0
        public bool CombineIfFull(PacketHeader header, IPEndPoint endPoint, ref ReceivedSmartPacket receivedPacket)
        {
            int fullLength = 0;

            // TODO: validate that headers of all fragments match
            var frag = GetFragmentedPacket(header);

            if (frag.Buffers.Count < header.FragCount)
            {
                return(false);
            }

            var buffersCount = frag.FragCount;

            for (int i = 0; i < buffersCount; ++i)
            {
                fullLength += frag.Buffers[i].Length;
            }

            byte[] combinedBuffer = _buffersPool.Get(fullLength);
            var    targetOffset   = 0;

            for (int i = 0; i < buffersCount; ++i)
            {
                var srcBuffer = frag.Buffers[i];
                Array.Copy(srcBuffer.Buffer, srcBuffer.Offset, combinedBuffer, targetOffset, srcBuffer.Length);
                targetOffset += frag.Buffers[i].Length;
                _buffersPool.Put(srcBuffer.Buffer);
            }

            // TODO: optimize?
            _frags.Remove(frag);
            _fragPacketsPool.Put(frag);

            // TODO: calculate it?
            bool inOrder = true;

            receivedPacket.Buffer   = combinedBuffer;
            receivedPacket.Offset   = 0;
            receivedPacket.Length   = fullLength;
            receivedPacket.EndPoint = endPoint;
            receivedPacket.InOrder  = inOrder;
            return(true);
        }
コード例 #8
0
ファイル: SmartSock.cs プロジェクト: pixonic/pixockets
        private bool OnReceiveFragment(byte[] buffer, int offset, int length, IPEndPoint endPoint, PacketHeader header, ref ReceivedSmartPacket receivedPacket)
        {
            var seqState = GetSeqStateOnReceive(endPoint, header);

            seqState.AddFragment(buffer, offset, length, header);

            return(seqState.CombineIfFull(header, endPoint, ref receivedPacket));
        }
コード例 #9
0
ファイル: SmartSock.cs プロジェクト: pixonic/pixockets
        private bool OnReceiveComplete(byte[] buffer, int offset, int length, IPEndPoint endPoint, PacketHeader header, bool inOrder, ref ReceivedSmartPacket receivedPacket)
        {
            var headerLen = header.HeaderLength;

            var payloadLength = length - headerLen;

            if (payloadLength > 0)
            {
                receivedPacket.Buffer   = buffer;
                receivedPacket.Offset   = offset + headerLen;
                receivedPacket.Length   = payloadLength;
                receivedPacket.EndPoint = endPoint;
                receivedPacket.InOrder  = inOrder;
                return(true);
            }

            return(false);
        }
コード例 #10
0
ファイル: SmartSock.cs プロジェクト: pixonic/pixockets
        private bool OnReceive(byte[] buffer, int offset, int length, IPEndPoint endPoint, ref ReceivedSmartPacket receivedPacket)
        {
            bool haveResult = false;

            var header = _headersPool.Get();

            header.Init(buffer, offset);

            var seqState = GetSeqStateOnReceive(endPoint, header);

            if (length != header.Length || seqState == null)
            {
                // Wrong packet
                _headersPool.Put(header);
                _buffersPool.Put(buffer);
                return(false);
            }

            // Update activity timestamp on receive packet
            seqState.LastActive = Environment.TickCount;
            if (seqState.CheckConnected())
            {
                // Send response only for request
                if (header.SessionId == PacketHeader.EmptySessionId)
                {
                    SendConnectionResponse(endPoint, seqState);
                }

                _callbacks.OnConnect(endPoint);
            }
            else if (header.SessionId == PacketHeader.EmptySessionId && (header.Flags & PacketHeader.Connect) != 0)
            {
                SendConnectionResponse(endPoint, seqState);
            }

            if (!seqState.IsConnected)
            {
                // Wrong packet
                _headersPool.Put(header);
                _buffersPool.Put(buffer);
                return(false);
            }

            if ((header.Flags & PacketHeader.ContainsFrag) != 0)
            {
                bool isDuplicate = seqState.IsDuplicate(header.SeqNum);
                if (!isDuplicate)
                {
                    haveResult = OnReceiveFragment(buffer, offset, length, endPoint, header, ref receivedPacket);
                    seqState.RegisterIncoming(header.SeqNum);
                }
            }
            else if ((header.Flags & PacketHeader.ContainsSeq) != 0)
            {
                bool isDuplicate = seqState.IsDuplicate(header.SeqNum);
                if (!isDuplicate)
                {
                    bool inOrder = seqState.IsInOrder(header.SeqNum);
                    haveResult = OnReceiveComplete(buffer, offset, length, endPoint, header, inOrder, ref receivedPacket);
                    seqState.RegisterIncoming(header.SeqNum);
                }
            }

            if ((header.Flags & PacketHeader.Disconnect) != 0)
            {
                // Disconnect request received, send response
                if (!seqState.DisconnectRequestSent)
                {
                    SendDisconnectPacket(endPoint, seqState);
                }

                _callbacks.OnDisconnect(endPoint, DisconnectReason.InitiatedByPeer);
                _seqStates.Remove(endPoint);
                _seqStatesPool.Put(seqState);
            }

            if ((header.Flags & PacketHeader.ContainsAck) != 0)
            {
                seqState.ReceiveAck(header.Acks);
            }

            if ((header.Flags & PacketHeader.NeedsAck) != 0)
            {
                seqState.EnqueueAck(header.SeqNum);
            }

            if (!haveResult && (header.Flags & PacketHeader.ContainsFrag) == 0)
            {
                _buffersPool.Put(buffer);
            }

            _headersPool.Put(header);

            return(haveResult);
        }