예제 #1
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();
        }
예제 #2
0
        /// <summary>
        /// Send the specified packet. Marks the buffer as used.
        /// </summary>

        public void SendTcpPacket(Buffer buffer, bool instant = false)
        {
#if !MODDING
            buffer.MarkAsUsed();

            var reader = buffer.BeginReading();

            if (buffer.size == 0)
            {
#if UNITY_EDITOR
                Debug.LogError("Trying to send a zero packet! " + buffer.position + " " + buffer.isWriting + " " + id);
#endif
                buffer.Recycle();
                return;
            }

#if DEBUG_PACKETS && !STANDALONE
            var 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 (custom != null)
            {
                if (!custom.SendPacket(buffer))
                {
                    buffer.Recycle();
                    Disconnect();
                }
                else
                {
                    buffer.Recycle();
                }
                return;
            }

            if (mSocket != null && mSocket.Connected)
            {
                lock (mOut)
                {
#if UNITY_WINRT
                    mSocket.Send(buffer.buffer, buffer.size, SocketFlags.None);
#else
                    if (instant)
                    {
                        try
                        {
                            var before = mSocket.NoDelay;
                            if (!before)
                            {
                                mSocket.NoDelay = true;
                            }
                            mSocket.Send(buffer.buffer, buffer.position, buffer.size, SocketFlags.None);
                            if (!before)
                            {
                                mSocket.NoDelay = false;
                            }
                            buffer.Recycle();
                            return;
                        }
                        catch { }
                    }

                    if (mSending)
                    {
                        // Simply add this packet to the outgoing queue
                        mOut.Enqueue(buffer);
                    }
                    else
                    {
                        // If it's the first packet, let's begin the send process
                        mSending = true;

                        try
                        {
                            mSocket.BeginSend(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, OnSend, buffer);
                        }
                        catch (System.Exception ex)
                        {
                            mOut.Clear();
                            buffer.Recycle();
                            AddError(ex);
                            CloseNotThreadSafe(false);
                            mSending = false;
                        }
                    }
#endif
                }
                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)
                {
                    lock (sendQueue) sendQueue.Enqueue(buffer);
                    return;
                }

                // Multi-part packet -- split it up into separate ones
                lock (sendQueue)
                {
                    for (;;)
                    {
                        var bytes  = reader.ReadBytes(size);
                        var temp   = Buffer.Create();
                        var writer = temp.BeginWriting();
                        writer.Write(size);
                        writer.Write(bytes);
                        temp.BeginReading(4);
                        sendQueue.Enqueue(temp);

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