Esempio n. 1
0
        /// <summary>
        ///     reads a message from connection
        /// </summary>
        /// <param name="buffer">buffer where the message will be written</param>
        /// <returns>true if we got a message, false if we got disconnected</returns>
        public void Receive()
        {
            if (!open)
            {
                OnDisconnected?.Invoke();
                Debug.LogWarning("DISCO a");
                return;
            }

            // read as long as we have things to read
            int msgSize;

            while ((msgSize = kcp.PeekSize()) > 0)
            {
                kcp.Receive(buffer, 0, msgSize);

                ArraySegment <byte> dataSegment = new ArraySegment <byte>(buffer, 0, msgSize);

                // handshake message?
                if (SegmentsEqual(dataSegment, Hello))
                {
                    // we are only connected if we received the handshake.
                    // not just after receiving any first data.
                    Debug.LogWarning("Kcp recv handshake");
                    OnConnected?.Invoke();
                }
                // disconnect message?
                else if (SegmentsEqual(dataSegment, Goodby))
                {
                    // if we receive a disconnect message,  then close everything
                    Debug.LogWarning("Kcp recv disconnected");
                    open = false;
                    OnDisconnected?.Invoke();
                }
                // otherwise regular message
                else
                {
                    //Debug.LogWarning($"Kcp recv msg: {BitConverter.ToString(buffer, 0, msgSize)}");
                    OnData?.Invoke(dataSegment);
                }
            }
        }
Esempio n. 2
0
        // reads the next message from connection.
        bool ReceiveNext(out ArraySegment <byte> message)
        {
            // read only one message
            int msgSize = kcp.PeekSize();

            if (msgSize > 0)
            {
                // only allow receiving up to MaxMessageSize sized messages.
                // otherwise we would get BlockCopy ArgumentException anyway.
                if (msgSize <= Kcp.MTU_DEF)
                {
                    int received = kcp.Receive(buffer, msgSize);
                    if (received >= 0)
                    {
                        message         = new ArraySegment <byte>(buffer, 0, msgSize);
                        lastReceiveTime = (uint)refTime.ElapsedMilliseconds;

                        // return false if it was a ping message. true otherwise.
                        if (Utils.SegmentsEqual(message, Ping))
                        {
                            //Debug.Log("KCP: received ping.");
                            return(false);
                        }
                        return(true);
                    }
                    else
                    {
                        // if receive failed, close everything
                        Debug.LogWarning($"Receive failed with error={received}. closing connection.");
                        Disconnect();
                    }
                }
                // we don't allow sending messages > Max, so this must be an
                // attacker. let's disconnect to avoid allocation attacks etc.
                else
                {
                    Debug.LogWarning($"KCP: possible allocation attack for msgSize {msgSize} > max {Kcp.MTU_DEF}. Disconnecting the connection.");
                    Disconnect();
                }
            }
            return(false);
        }
Esempio n. 3
0
        // reads the next reliable message type & content from kcp.
        // -> to avoid buffering, unreliable messages call OnData directly.
        bool ReceiveNextReliable(out KcpHeader header, out ArraySegment <byte> message)
        {
            int msgSize = kcp.PeekSize();

            if (msgSize > 0)
            {
                // only allow receiving up to buffer sized messages.
                // otherwise we would get BlockCopy ArgumentException anyway.
                if (msgSize <= kcpMessageBuffer.Length)
                {
                    // receive from kcp
                    int received = kcp.Receive(kcpMessageBuffer, msgSize);
                    if (received >= 0)
                    {
                        // extract header & content without header
                        header          = (KcpHeader)kcpMessageBuffer[0];
                        message         = new ArraySegment <byte>(kcpMessageBuffer, 1, msgSize - 1);
                        lastReceiveTime = (uint)refTime.ElapsedMilliseconds;
                        return(true);
                    }
                    else
                    {
                        // if receive failed, close everything
                        // pass error to user callback. no need to log it manually.
                        OnError(ErrorCode.InvalidReceive, $"Receive failed with error={received}. closing connection.");
                        Disconnect();
                    }
                }
                // we don't allow sending messages > Max, so this must be an
                // attacker. let's disconnect to avoid allocation attacks etc.
                else
                {
                    // pass error to user callback. no need to log it manually.
                    OnError(ErrorCode.InvalidReceive, $"KCP: possible allocation attack for msgSize {msgSize} > buffer {kcpMessageBuffer.Length}. Disconnecting the connection.");
                    Disconnect();
                }
            }

            message = default;
            header  = KcpHeader.Disconnect;
            return(false);
        }