コード例 #1
0
ファイル: TNBuffer.cs プロジェクト: bojobiscuit/OnlineGame
		/// <summary>
		/// Copy the contents of this buffer into the target one, trimming away unused space.
		/// </summary>

		public void CopyTo (Buffer target)
		{
			BinaryWriter w = target.BeginWriting(false);
			int bytes = size;
			if (bytes > 0) w.Write(buffer, position, bytes);
			target.EndWriting();
		}
コード例 #2
0
        /// <summary>
        /// Create a new buffered remote function call.
        /// </summary>

        public void CreateRFC(uint inID, string funcName, Buffer buffer)
        {
            if (closed || buffer == null)
            {
                return;
            }

            Buffer b = Buffer.Create();

            b.BeginWriting(false).Write(buffer.buffer, buffer.position, buffer.size);
            b.BeginReading();

            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC r = rfcs[i];

                if (r.uid == inID && r.functionName == funcName)
                {
                    if (r.buffer != null)
                    {
                        r.buffer.Recycle();
                    }
                    r.buffer = b;
                    return;
                }
            }

            RFC rfc = new RFC();

            rfc.uid          = inID;
            rfc.buffer       = b;
            rfc.functionName = funcName;
            rfcs.Add(rfc);
        }
コード例 #3
0
        /// <summary>
        /// Add a new saved remote function call.
        /// </summary>

        public void AddRFC(uint uid, string funcName, Buffer buffer)
        {
            if (closed || buffer == null)
            {
                return;
            }
            uint objID = (uid >> 8);

            // Ignore objects that don't exist
            if (objID < 32768)
            {
                if (destroyed.Contains(objID))
                {
                    return;
                }
            }
            else if (!mCreatedObjectDictionary.ContainsKey(objID))
            {
                return;
            }

            Buffer b = Buffer.Create();

            b.BeginWriting(false).Write(buffer.buffer, buffer.position, buffer.size);
            b.EndWriting();

            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC r = rfcs[i];

                if (r.uid == uid && r.functionName == funcName)
                {
                    if (r.data != null)
                    {
                        r.data.Recycle();
                    }
                    r.data = b;
                    return;
                }
            }

            RFC rfc = new RFC();

            rfc.uid          = uid;
            rfc.data         = b;
            rfc.functionName = funcName;
            rfcs.Add(rfc);
        }
コード例 #4
0
        /// <summary>
        /// Receive incoming data.
        /// </summary>

        void OnReceive(IAsyncResult result)
        {
            if (!isActive)
            {
                return;
            }
            int bytes = 0;

            try
            {
                bytes = mSocket.EndReceiveFrom(result, ref mEndPoint);
            }
            catch (System.Exception ex)
            {
                Error(new IPEndPoint(Tools.localAddress, 0), ex.Message);
            }

            if (bytes > 4)
            {
                // This datagram is now ready to be processed
                Buffer buffer = Buffer.Create();
                buffer.BeginWriting(false).Write(mTemp, 0, bytes);
                buffer.BeginReading(4);

                // The 'endPoint', gets reassigned rather than updated.
                Datagram dg = new Datagram();
                dg.buffer = buffer;
                dg.ip     = (IPEndPoint)mEndPoint;
                lock (mIn) mIn.Enqueue(dg);
            }

            // Queue up the next receive operation
            if (mSocket != null)
            {
                mEndPoint = mDefaultEndPoint;

                try
                {
                    mSocket.BeginReceiveFrom(mTemp, 0, mTemp.Length, SocketFlags.None, ref mEndPoint, OnReceive, null);
                }
                catch (System.Exception ex)
                {
                    Error(new IPEndPoint(Tools.localAddress, 0), ex.Message);
                }
            }
        }
コード例 #5
0
ファイル: TNTcpProtocol.cs プロジェクト: qipa/IceAge-Unity
        /// <summary>
        /// See if the received packet can be processed and split it up into different ones.
        /// </summary>

        bool ProcessBuffer(int bytes)
        {
            if (mReceiveBuffer == null)
            {
                // Create a new packet buffer
                mReceiveBuffer = Buffer.Create();
                mReceiveBuffer.BeginWriting(false).Write(mTemp, 0, bytes);
            }
            else
            {
                // Append this data to the end of the last used buffer
                mReceiveBuffer.BeginWriting(true).Write(mTemp, 0, bytes);
            }

            for (int available = mReceiveBuffer.size - mOffset; available >= 4;)
            {
                // Figure out the expected size of the packet
                if (mExpected == 0)
                {
                    mExpected = mReceiveBuffer.PeekInt(mOffset);

                    if (mExpected < 0 || mExpected > 16777216)
                    {
                        Close(true);
                        return(false);
                    }
                }

                // The first 4 bytes of any packet always contain the number of bytes in that packet
                available -= 4;

                // If the entire packet is present
                if (available == mExpected)
                {
                    // Reset the position to the beginning of the packet
                    mReceiveBuffer.BeginReading(mOffset + 4);

                    // This packet is now ready to be processed
                    lock (mIn) mIn.Enqueue(mReceiveBuffer);

                    mReceiveBuffer = null;
                    mExpected      = 0;
                    mOffset        = 0;
                    break;
                }
                else if (available > mExpected)
                {
                    // There is more than one packet. Extract this packet fully.
                    int    realSize = mExpected + 4;
                    Buffer temp     = Buffer.Create();

                    // Extract the packet and move past its size component
                    temp.BeginWriting(false).Write(mReceiveBuffer.buffer, mOffset, realSize);
                    temp.BeginReading(4);

                    // This packet is now ready to be processed
                    lock (mIn) mIn.Enqueue(temp);

                    // Skip this packet
                    available -= mExpected;
                    mOffset   += realSize;
                    mExpected  = 0;
                }
                else
                {
                    break;
                }
            }
            return(true);
        }
コード例 #6
0
        /// <summary>
        /// Load the channel's data from the specified file.
        /// </summary>

        public bool LoadFrom(BinaryReader reader)
        {
            int version = reader.ReadInt32();

            if (version < 20160207)
            {
#if UNITY_EDITOR
                UnityEngine.Debug.LogWarning("Incompatible data: " + version);
#endif
                return(false);
            }

            // Clear all RFCs, just in case
            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC r = rfcs[i];
                if (r.data != null)
                {
                    r.data.Recycle();
                }
            }

            rfcs.Clear();
            created.Clear();
            destroyed.Clear();
            mCreatedObjectDictionary.Clear();

            level         = reader.ReadString();
            dataNode      = reader.ReadDataNode();
            objectCounter = reader.ReadUInt32();
            password      = reader.ReadString();
            persistent    = reader.ReadBoolean();
            playerLimit   = reader.ReadUInt16();

            int size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
                RFC rfc = new RFC();
                rfc.uid = reader.ReadUInt32();
                if (rfc.functionID == 0)
                {
                    rfc.functionName = reader.ReadString();
                }
                Buffer b = Buffer.Create();
                b.BeginWriting(false).Write(reader.ReadBytes(reader.ReadInt32()));
                b.EndWriting();
                rfc.data = b;
                rfcs.Add(rfc);
            }

            size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
                CreatedObject co = new CreatedObject();
                co.playerID = reader.ReadInt32();
                co.objectID = reader.ReadUInt32();
                co.type     = 1;
                Buffer b = Buffer.Create();
                b.BeginWriting(false).Write(reader.ReadBytes(reader.ReadInt32()));
                b.EndWriting();
                co.buffer = b;
                AddCreatedObject(co);
            }

            size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
                uint uid = reader.ReadUInt32();
                if (uid < 32768)
                {
                    destroyed.Add(uid);
                }
            }

            isLocked = reader.ReadBoolean();
            return(true);
        }
コード例 #7
0
        /// <summary>
        /// Channel joining process involves multiple steps. It's faster to perform them all at once.
        /// </summary>

        public void FinishJoiningChannel()
        {
            Buffer buffer = Buffer.Create();

            // Step 2: Tell the player who else is in the channel
            BinaryWriter writer = buffer.BeginPacket(Packet.ResponseJoiningChannel);
            {
                writer.Write(channel.id);
                writer.Write((short)channel.players.size);

                for (int i = 0; i < channel.players.size; ++i)
                {
                    TcpPlayer tp = channel.players[i];
                    writer.Write(tp.id);
                    writer.Write(string.IsNullOrEmpty(tp.name) ? "Guest" : tp.name);
                }
            }

            // End the first packet, but remember where it ended
            int offset = buffer.EndPacket();

            // Step 3: Inform the player of who is hosting
            if (channel.host == null)
            {
                channel.host = this;
            }
            buffer.BeginPacket(Packet.ResponseSetHost, offset);
            writer.Write(channel.host.id);
            offset = buffer.EndTcpPacketStartingAt(offset);

            // Step 4: Send the channel's data
            if (!string.IsNullOrEmpty(channel.data))
            {
                buffer.BeginPacket(Packet.ResponseSetChannelData, offset);
                writer.Write(channel.data);
                offset = buffer.EndTcpPacketStartingAt(offset);
            }

            // Step 5: Inform the player of what level we're on
            buffer.BeginPacket(Packet.ResponseLoadLevel, offset);
            writer.Write(string.IsNullOrEmpty(channel.level) ? "" : channel.level);
            offset = buffer.EndTcpPacketStartingAt(offset);

            // Step 6: Send the list of objects that have been created
            for (int i = 0; i < channel.created.size; ++i)
            {
                Channel.CreatedObject obj = channel.created.buffer[i];
                buffer.BeginPacket(Packet.ResponseCreate, offset);
                writer.Write(obj.playerID);
                writer.Write(obj.objectID);
                writer.Write(obj.uniqueID);
                writer.Write(obj.buffer.buffer, obj.buffer.position, obj.buffer.size);
                offset = buffer.EndTcpPacketStartingAt(offset);
            }

            // Step 7: Send the list of objects that have been destroyed
            if (channel.destroyed.size != 0)
            {
                buffer.BeginPacket(Packet.ResponseDestroy, offset);
                writer.Write((ushort)channel.destroyed.size);
                for (int i = 0; i < channel.destroyed.size; ++i)
                {
                    writer.Write(channel.destroyed.buffer[i]);
                }
                offset = buffer.EndTcpPacketStartingAt(offset);
            }

            // Step 8: Send all buffered RFCs to the new player
            for (int i = 0; i < channel.rfcs.size; ++i)
            {
                Buffer rfcBuff = channel.rfcs[i].buffer;
                rfcBuff.BeginReading();
                buffer.BeginWriting(offset);
                writer.Write(rfcBuff.buffer, rfcBuff.position, rfcBuff.size);
                offset = buffer.EndWriting();
            }

            // Step 9: The join process is now complete
            buffer.BeginPacket(Packet.ResponseJoinChannel, offset);
            writer.Write(true);
            offset = buffer.EndTcpPacketStartingAt(offset);

            // Send the entire buffer
            SendTcpPacket(buffer);
            buffer.Recycle();
        }
コード例 #8
0
ファイル: TNBuffer.cs プロジェクト: jeffmun/BalloonPop
 /// <summary>
 /// Copy the contents of this buffer into the target one, trimming away unused space.
 /// </summary>
 public void CopyTo(Buffer target)
 {
     BinaryWriter w = target.BeginWriting(false);
     int bytes = size;
     if (bytes > 0) w.Write(buffer, position, bytes);
     target.EndWriting();
 }
コード例 #9
0
        /// <summary>
        /// See if the received packet can be processed and split it up into different ones.
        /// </summary>

        bool ProcessBuffer(int bytes)
        {
            if (mReceiveBuffer == null)
            {
                // Create a new packet buffer
                mReceiveBuffer = Buffer.Create();
                mReceiveBuffer.BeginWriting(false).Write(mTemp, 0, bytes);
                mExpected = 0;
                mOffset   = 0;
            }
            else
            {
                // Append this data to the end of the last used buffer
                mReceiveBuffer.BeginWriting(true).Write(mTemp, 0, bytes);
            }

            for (int available = mReceiveBuffer.size - mOffset; available >= 4;)
            {
                // Figure out the expected size of the packet
                if (mExpected == 0)
                {
                    mExpected = mReceiveBuffer.PeekInt(mOffset);

                    // "GET " -- HTTP GET request sent by a web browser
                    if (mExpected == 542393671)
                    {
                        if (httpGetSupport)
                        {
                            if (stage == Stage.Verifying || stage == Stage.WebBrowser)
                            {
                                stage = Stage.WebBrowser;
                                string request = Encoding.ASCII.GetString(mReceiveBuffer.buffer, mOffset, available);
                                mReceiveBuffer.BeginPacket(Packet.RequestHTTPGet).Write(request);
                                mReceiveBuffer.EndPacket();
                                mReceiveBuffer.BeginReading(4);
                                lock (mIn) mIn.Enqueue(mReceiveBuffer);
                                mReceiveBuffer = null;
                                mExpected      = 0;
                                mOffset        = 0;
                            }
                            return(true);
                        }

                        mReceiveBuffer.Recycle();
                        mReceiveBuffer = null;
                        mExpected      = 0;
                        mOffset        = 0;
                        Disconnect();
                        return(false);
                    }
                    else if (mExpected < 0 || mExpected > 16777216)
                    {
#if UNITY_EDITOR
                        UnityEngine.Debug.LogError("Malformed data packet: " + mOffset + ", " + available + " / " + mExpected);
#else
                        Tools.LogError("Malformed data packet: " + mOffset + ", " + available + " / " + mExpected);
#endif
                        mReceiveBuffer.Recycle();
                        mReceiveBuffer = null;
                        mExpected      = 0;
                        mOffset        = 0;
                        Disconnect();
                        return(false);
                    }
                }

                // The first 4 bytes of any packet always contain the number of bytes in that packet
                available -= 4;

                // If the entire packet is present
                if (available == mExpected)
                {
                    // Reset the position to the beginning of the packet
                    mReceiveBuffer.BeginReading(mOffset + 4);

                    // This packet is now ready to be processed
                    lock (mIn) mIn.Enqueue(mReceiveBuffer);

                    mReceiveBuffer = null;
                    mExpected      = 0;
                    mOffset        = 0;
                    break;
                }
                else if (available > mExpected)
                {
                    // There is more than one packet. Extract this packet fully.
                    int    realSize = mExpected + 4;
                    Buffer temp     = Buffer.Create();

                    // Extract the packet and move past its size component
                    BinaryWriter bw = temp.BeginWriting(false);
                    bw.Write(mReceiveBuffer.buffer, mOffset, realSize);
                    temp.BeginReading(4);

                    // This packet is now ready to be processed
                    lock (mIn) mIn.Enqueue(temp);

                    // Skip this packet
                    available -= mExpected;
                    mOffset   += realSize;
                    mExpected  = 0;
                }
                else
                {
                    break;
                }
            }
            return(true);
        }
コード例 #10
0
        /// <summary>
        /// Send the specified packet. Marks the buffer as used.
        /// </summary>

        public void SendTcpPacket(Buffer buffer)
        {
            buffer.MarkAsUsed();
            BinaryReader reader = buffer.BeginReading();

#if DEBUG_PACKETS && !STANDALONE
            Packet packet = (Packet)buffer.PeekByte(4);
            if (packet != Packet.RequestPing && packet != Packet.ResponsePing)
            {
                UnityEngine.Debug.Log("Sending: " + packet + " to " + name + " (" + (buffer.size - 5).ToString("N0") + " bytes)");
            }
#endif

            if (mSocket != null && mSocket.Connected)
            {
                lock (mOut)
                {
                    mOut.Enqueue(buffer);

                    // If it's the first packet, let's begin the send process
                    if (mOut.Count == 1)
                    {
                        try
                        {
#if !UNITY_WINRT
                            mSocket.BeginSend(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, OnSend, buffer);
#endif
                        }
                        catch (System.Exception ex)
                        {
                            mOut.Clear();
                            buffer.Recycle();
                            RespondWithError(ex);
                            CloseNotThreadSafe(false);
                        }
                    }
                }
                return;
            }

            if (sendQueue != null)
            {
                if (buffer.position != 0)
                {
                    // Offline mode sends packets individually and they should not be reused
#if UNITY_EDITOR
                    Debug.LogWarning("Packet's position is " + buffer.position + " instead of 0. Potentially sending the same packet more than once. Ignoring...");
#endif
                    return;
                }

                // Skip the packet's size
                int size = reader.ReadInt32();

                if (size == buffer.size)
                {
                    // Note that after this the buffer can no longer be used again as its offset is +4
                    lock (sendQueue) sendQueue.Enqueue(buffer);
                    return;
                }

                // Multi-part packet -- split it up into separate ones
                lock (sendQueue)
                {
                    for (;;)
                    {
                        byte[] bytes = reader.ReadBytes(size);

                        Buffer       temp   = Buffer.Create();
                        BinaryWriter writer = temp.BeginWriting();
                        writer.Write(size);
                        writer.Write(bytes);
                        temp.BeginReading(4);
                        temp.EndWriting();
                        sendQueue.Enqueue(temp);

                        if (buffer.size > 0)
                        {
                            size = reader.ReadInt32();
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }

            buffer.Recycle();
        }
コード例 #11
0
        /// <summary>
        /// Load the channel's data from the specified file.
        /// </summary>

        public bool LoadFrom(BinaryReader reader)
        {
            int version = reader.ReadInt32();

            if (version != Player.version)
            {
                return(false);
            }

            // Clear all RFCs, just in case
            for (int i = 0; i < rfcs.size; ++i)
            {
                RFC r = rfcs[i];
                if (r.buffer != null)
                {
                    r.buffer.Recycle();
                }
            }
            rfcs.Clear();
            created.Clear();
            destroyed.Clear();

            level         = reader.ReadString();
            data          = reader.ReadString();
            objectCounter = reader.ReadUInt32();
            password      = reader.ReadString();
            persistent    = reader.ReadBoolean();
            playerLimit   = reader.ReadUInt16();

            int size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
                RFC rfc = new RFC();
                rfc.id = reader.ReadUInt32();
                Buffer b = Buffer.Create();
                b.BeginWriting(false).Write(reader.ReadBytes(reader.ReadInt32()));
                rfc.buffer = b;
                rfcs.Add(rfc);
            }

            size = reader.ReadInt32();

            for (int i = 0; i < size; ++i)
            {
                CreatedObject co = new CreatedObject();
                co.playerID = reader.ReadInt32();
                co.uniqueID = reader.ReadUInt32();
                co.objectID = reader.ReadUInt16();
                Buffer b = Buffer.Create();
                b.BeginWriting(false).Write(reader.ReadBytes(reader.ReadInt32()));
                co.buffer = b;
                created.Add(co);
            }

            size = reader.ReadInt32();
            for (int i = 0; i < size; ++i)
            {
                destroyed.Add(reader.ReadUInt32());
            }
            return(true);
        }
コード例 #12
0
        /// <summary>
        /// Channel joining process involves multiple steps. It's faster to perform them all at once.
        /// </summary>

        public void FinishJoiningChannel()
        {
            Buffer buffer = Buffer.Create();

            // Step 2: Tell the player who else is in the channel
            BinaryWriter writer = buffer.BeginPacket(Packet.ResponseJoiningChannel);
            {
                writer.Write(channel.id);
                writer.Write((short)channel.players.size);

                for (int i = 0; i < channel.players.size; ++i)
                {
                    TcpPlayer tp = channel.players[i];
                    writer.Write(tp.id);
                    writer.Write(string.IsNullOrEmpty(tp.name) ? "Guest" : tp.name);
#if STANDALONE
                    if (tp.data == null)
                    {
                        writer.Write((byte)0);
                    }
                    else
                    {
                        writer.Write((byte[])tp.data);
                    }
#else
                    writer.WriteObject(tp.data);
#endif
                }
            }

            // End the first packet, but remember where it ended
            int offset = buffer.EndPacket();

            // Step 3: Inform the player of who is hosting
            if (channel.host == null)
            {
                channel.host = this;
            }
            buffer.BeginPacket(Packet.ResponseSetHost, offset);
            writer.Write(channel.host.id);
            offset = buffer.EndTcpPacketStartingAt(offset);

            // Step 4: Send the channel's data
            if (!string.IsNullOrEmpty(channel.data))
            {
                buffer.BeginPacket(Packet.ResponseSetChannelData, offset);
                writer.Write(channel.data);
                offset = buffer.EndTcpPacketStartingAt(offset);
            }

            // Step 5: Inform the player of what level we're on
            buffer.BeginPacket(Packet.ResponseLoadLevel, offset);
            writer.Write(string.IsNullOrEmpty(channel.level) ? "" : channel.level);
            offset = buffer.EndTcpPacketStartingAt(offset);

            // Step 6: Send the list of objects that have been created
            for (int i = 0; i < channel.created.size; ++i)
            {
                Channel.CreatedObject obj = channel.created.buffer[i];

                bool isPresent = false;

                for (int b = 0; b < channel.players.size; ++b)
                {
                    if (channel.players[b].id == obj.playerID)
                    {
                        isPresent = true;
                        break;
                    }
                }

                // If the previous owner is not present, transfer ownership to the host
                if (!isPresent)
                {
                    obj.playerID = channel.host.id;
                }

                buffer.BeginPacket(Packet.ResponseCreate, offset);
                writer.Write(obj.playerID);
                writer.Write(obj.objectIndex);
                writer.Write(obj.objectID);
                writer.Write(obj.buffer.buffer, obj.buffer.position, obj.buffer.size);
                offset = buffer.EndTcpPacketStartingAt(offset);
            }

            // Step 7: Send the list of objects that have been destroyed
            if (channel.destroyed.size != 0)
            {
                buffer.BeginPacket(Packet.ResponseDestroy, offset);
                writer.Write((ushort)channel.destroyed.size);
                for (int i = 0; i < channel.destroyed.size; ++i)
                {
                    writer.Write(channel.destroyed.buffer[i]);
                }
                offset = buffer.EndTcpPacketStartingAt(offset);
            }

            // Step 8: Send all buffered RFCs to the new player
            for (int i = 0; i < channel.rfcs.size; ++i)
            {
                Channel.RFC rfc = channel.rfcs[i];
                buffer.BeginWriting(offset);
                writer.Write(rfc.buffer.buffer, 0, rfc.buffer.size);
                offset = buffer.EndWriting();
            }

            // Step 9: The join process is now complete
            buffer.BeginPacket(Packet.ResponseJoinChannel, offset);
            writer.Write(true);
            offset = buffer.EndTcpPacketStartingAt(offset);

            // Send the entire buffer
            SendTcpPacket(buffer);
            buffer.Recycle();
        }
コード例 #13
0
        /// <summary>
        /// See if the received packet can be processed and split it up into different ones.
        /// </summary>

        bool ProcessBuffer(byte[] bytes, int offset, int byteCount)
        {
            if (offset + byteCount > bytes.Length)
            {
                LogError("ProcessBuffer(" + bytes.Length + " bytes, offset " + offset + ", count " + byteCount);
                return(false);
            }

            if (mReceiveBuffer == null)
            {
                // Create a new packet buffer
                mReceiveBuffer = Buffer.Create();
                mReceiveBuffer.BeginWriting(false).Write(bytes, offset, byteCount);
                mExpected = 0;
                mOffset   = 0;
            }
            else
            {
                // Append this data to the end of the last used buffer
                mReceiveBuffer.BeginWriting(true).Write(bytes, offset, byteCount);
            }

            for (mAvailable = mReceiveBuffer.size - mOffset; mAvailable > 4;)
            {
                // Figure out the expected size of the packet
                if (mExpected == 0)
                {
                    mExpected = mReceiveBuffer.PeekInt(mOffset);

                    // "GET " -- HTTP GET request sent by a web browser
                    if (mExpected == 542393671)
                    {
                        if (httpGetSupport)
                        {
                            if (stage == Stage.Verifying || stage == Stage.WebBrowser)
                            {
                                stage = Stage.WebBrowser;
                                string request = Encoding.ASCII.GetString(mReceiveBuffer.buffer, mOffset, mAvailable);
                                mReceiveBuffer.BeginPacket(Packet.RequestHTTPGet).Write(request);
                                mReceiveBuffer.EndPacket();
                                mReceiveBuffer.BeginReading(4);

                                lock (mIn)
                                {
                                    mIn.Enqueue(mReceiveBuffer);
                                    mReceiveBuffer = null;
                                    mExpected      = 0;
                                    mOffset        = 0;
                                }
                            }
                            return(true);
                        }

                        mReceiveBuffer.Recycle();
                        mReceiveBuffer = null;
                        mExpected      = 0;
                        mOffset        = 0;
                        Disconnect();
                        return(false);
                    }
                    else if (mExpected < 0 || mExpected > 16777216)
                    {
#if UNITY_EDITOR
                        LogError("Malformed data packet: " + mOffset + ", " + mAvailable + " / " + mExpected);

                        var temp = new byte[mReceiveBuffer.size];
                        for (int i = 0; i < byteCount; ++i)
                        {
                            temp[i] = mReceiveBuffer.buffer[i];
                        }

                        var fn = "error_" + lastReceivedTime + ".full";
                        Tools.WriteFile(fn, temp);
                        Debug.Log("Packet saved as " + fn);
#else
                        LogError("Malformed data packet: " + mOffset + ", " + mAvailable + " / " + mExpected);
#endif
                        mReceiveBuffer.Recycle();
                        mReceiveBuffer = null;
                        mExpected      = 0;
                        mOffset        = 0;
                        Disconnect();
                        return(false);
                    }
                }

                // The first 4 bytes of any packet always contain the number of bytes in that packet
                mAvailable -= 4;

                // If the entire packet is present
                if (mAvailable == mExpected)
                {
                    // Reset the position to the beginning of the packet
                    mReceiveBuffer.BeginReading(mOffset + 4);

                    // This packet is now ready to be processed
                    lock (mIn)
                    {
                        mIn.Enqueue(mReceiveBuffer);
                        mReceiveBuffer = null;
                        mExpected      = 0;
                        mOffset        = 0;
                    }
                    break;
                }
                else if (mAvailable > mExpected)
                {
                    // There is more than one packet. Extract this packet fully.
                    int realSize = mExpected + 4;
                    var temp     = Buffer.Create();

                    // Extract the packet and move past its size component
                    var bw = temp.BeginWriting();
                    bw.Write(mReceiveBuffer.buffer, mOffset, realSize);
                    temp.BeginReading(4);

                    // This packet is now ready to be processed
                    lock (mIn)
                    {
                        mIn.Enqueue(temp);

                        // Skip this packet
                        mAvailable -= mExpected;
                        mOffset    += realSize;
                        mExpected   = 0;
                    }
                }
                else
                {
                    break;
                }
            }
            return(true);
        }
コード例 #14
0
ファイル: TNTcpProtocol.cs プロジェクト: jeffmun/BalloonPop
        /// <summary>
        /// See if the received packet can be processed and split it up into different ones.
        /// </summary>
        bool ProcessBuffer(int bytes)
        {
            if (mReceiveBuffer == null)
            {
            // Create a new packet buffer
            mReceiveBuffer = Buffer.Create();
            mReceiveBuffer.BeginWriting(false).Write(mTemp, 0, bytes);
            }
            else
            {
            // Append this data to the end of the last used buffer
            mReceiveBuffer.BeginWriting(true).Write(mTemp, 0, bytes);
            }

            for (int available = mReceiveBuffer.size - mOffset; available >= 4; )
            {
            // Figure out the expected size of the packet
            if (mExpected == 0)
            {
                mExpected = mReceiveBuffer.PeekInt(mOffset);
                if (mExpected == -1) break;

                if (mExpected == 0)
                {
                    Close(true);
                    return false;
                }
            }

            // The first 4 bytes of any packet always contain the number of bytes in that packet
            available -= 4;

            // If the entire packet is present
            if (available == mExpected)
            {
                // Reset the position to the beginning of the packet
                mReceiveBuffer.BeginReading(mOffset + 4);

                // This packet is now ready to be processed
                lock (mIn) mIn.Enqueue(mReceiveBuffer);

                mReceiveBuffer = null;
                mExpected = 0;
                mOffset = 0;
                break;
            }
            else if (available > mExpected)
            {
                // There is more than one packet. Extract this packet fully.
                int realSize = mExpected + 4;
                Buffer temp = Buffer.Create();

                // Extract the packet and move past its size component
                temp.BeginWriting(false).Write(mReceiveBuffer.buffer, mOffset, realSize);
                temp.BeginReading(4);

                // This packet is now ready to be processed
                lock (mIn) mIn.Enqueue(temp);

                // Skip this packet
                available -= mExpected;
                mOffset += realSize;
                mExpected = 0;
            }
            else break;
            }
            return true;
        }