示例#1
0
        private bool ReceiveToPackageBuffer(byte[] buffer
                                            , ref int remainCount
                                            , ref int readPosition
                                            , ArrayPool <byte> .Node receiveBuffer
                                            , int targetSize)
        {
            int needReadCount = Mathf.Min(targetSize - m_ReceivedPackageCount
                                          , remainCount);

            Array.Copy(buffer
                       , readPosition
                       , receiveBuffer.GetBuffer()
                       , receiveBuffer.GetOffset() + m_ReceivedPackageCount
                       , needReadCount);
            remainCount            -= needReadCount;
            readPosition           += needReadCount;
            m_ReceivedPackageCount += needReadCount;

            if (m_ReceivedPackageCount == targetSize)
            {
                m_ReceivedPackageCount = 0;
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#2
0
        private void StartSend()
        {
            lock (m_SendEventArgs)
            {
                if (m_IsSending)
                {
                    return;
                }

                if (m_WaitSendBufferSize == 0)
                {
                    return;
                }

                m_IsSending = true;

                ArrayPool <byte> .Node swapBuffer = m_SendingBuffer;
                m_SendingBuffer  = m_WaitSendBuffer;
                m_WaitSendBuffer = swapBuffer;

                m_SendEventArgs.SetBuffer(m_SendingBuffer.GetBuffer()
                                          , m_SendingBuffer.GetOffset()
                                          , m_WaitSendBufferSize);
                m_WaitSendBufferSize = 0;
            }

            if (!m_Client.SendAsync(m_SendEventArgs))
            {
                ProcessSend(m_Client, m_SendEventArgs);
            }
        }
示例#3
0
        public unsafe void Send(byte[] data, int offset, int count)
        {
            if (!IsConnected())
            {
                MDebug.LogError(LOG_TAG, $"Client({GetName()}) 并未连接,无法发送数据");
                return;
            }

            byte[] buffer        = m_WaitSendBuffer.GetBuffer();
            int    writePosition = m_WaitSendBuffer.GetOffset() + m_WaitSendBufferSize;

            fixed(byte *pBuffer = &buffer[writePosition])
            {
                *((TLength *)pBuffer) = PACKAGE_HEADER_SIZE + count;
                writePosition        += PACKAGE_HEADER_SIZE;
                m_WaitSendBufferSize += PACKAGE_HEADER_SIZE;
            }

            Array.Copy(data
                       , offset
                       , m_WaitSendBuffer.GetBuffer()
                       , writePosition
                       , count);
            m_WaitSendBufferSize += count;

            StartSend();
        }
示例#4
0
        private void ProcessConnect(object sender, SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                MDebug.Log(LOG_TAG, $"Client({GetName()}) 连接成功");


                m_BufferPool = new ArrayPool <byte>(1024 * 512);
                lock (m_TcpConnectActionLock)
                {
                    m_TcpConnectData = new TcpConnectData(this, e, ConnectState.Connected);
                }
                m_IsSending = false;

                lock (m_BufferPool)
                {
                    m_SendEventArgs            = new SocketAsyncEventArgs();
                    m_SendEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(ProcessSend);
                    m_SendingBuffer            = m_BufferPool.AllocBuffer(DEFAULT_BUFFER_SIZE);
                    m_WaitSendBuffer           = m_BufferPool.AllocBuffer(DEFAULT_BUFFER_SIZE);
                    m_WaitSendBufferSize       = 0;
                    m_SendEventArgs.SetBuffer(m_SendingBuffer.GetBuffer(), m_SendingBuffer.GetOffset(), 0);

                    m_ReceiveEventArgs            = new SocketAsyncEventArgs();
                    m_ReceiveEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(ProcessReceive);
                    m_ReceiveBuffer = m_BufferPool.AllocBuffer(DEFAULT_BUFFER_SIZE);
                    m_ReceiveEventArgs.SetBuffer(m_ReceiveBuffer.GetBuffer(), m_ReceiveBuffer.GetOffset(), m_ReceiveBuffer.GetSize());

                    m_ReceiveState         = ReceiveState.ReceivingPackageLength;
                    m_ReceivedPackageCount = 0;
                    m_ReceiveHeaderBuffer  = m_BufferPool.AllocBuffer(PACKAGE_HEADER_SIZE);
                }

                lock (m_ReceiveLock)
                {
                    m_ReceivedPackages  = new Queue <ArrayPool <byte> .Node>();
                    m_ReceivedPackages2 = new BetterList <ArrayPool <byte> .Node>(4);
                    m_ReceivedPackages2._SetCount(m_ReceivedPackages2.Capacity);
                }

                StartReceive();
            }
            else
            {
                MDebug.LogError(LOG_TAG
                                , $"Client({GetName()}) 连接失败: {e.SocketError.ToString()}\n{e.ConnectByNameError.ToString()}");
                lock (m_TcpConnectActionLock)
                {
                    m_TcpConnectData = new TcpConnectData(this, e, ConnectState.ConnectFailed);
                }

                m_Client.Close();
                m_Client = null;
            }
        }
示例#5
0
        private void OnReceived(byte[] buffer, int offset, int count)
        {
            int remainCount  = count;
            int readPosition = offset;

            while (remainCount > 0)
            {
                switch (m_ReceiveState)
                {
                case ReceiveState.ReceivingPackageLength:
                    if (ReceiveToPackageBuffer(buffer
                                               , ref remainCount
                                               , ref readPosition
                                               , m_ReceiveHeaderBuffer
                                               , PACKAGE_HEADER_SIZE))
                    {
                        // SIGN:TLength
                        TLength packageLength = BitConverter.ToInt32(m_ReceiveHeaderBuffer.GetBuffer()
                                                                     , m_ReceiveHeaderBuffer.GetOffset());
                        lock (m_BufferPool)
                        {
                            m_ReceiveBodyBuffer = m_BufferPool.AllocBuffer(packageLength - PACKAGE_HEADER_SIZE);
                        }

                        m_ReceiveState = ReceiveState.ReceivingPackageBody;
                    }
                    break;

                case ReceiveState.ReceivingPackageBody:
                    if (ReceiveToPackageBuffer(buffer
                                               , ref remainCount
                                               , ref readPosition
                                               , m_ReceiveBodyBuffer
                                               , m_ReceiveBodyBuffer.GetSize()))
                    {
                        lock (m_ReceiveLock)
                        {
                            m_ReceivedPackages.Enqueue(m_ReceiveBodyBuffer);
                        }

                        m_ReceiveBodyBuffer = null;
                        m_ReceiveState      = ReceiveState.ReceivingPackageLength;
                    }
                    break;
                }
            }
        }
示例#6
0
        private void ProcessReceive(object sender, SocketAsyncEventArgs e)
        {
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                MDebug.LogVerbose(LOG_TAG
                                  , $"Client({GetName()}) 接收长度: {e.BytesTransferred}");

                OnReceived(m_ReceiveBuffer.GetBuffer()
                           , m_ReceiveBuffer.GetOffset()
                           , e.BytesTransferred);

                StartReceive();
            }
            else
            {
                MDebug.LogError(LOG_TAG
                                , $"Client({GetName()}) 接受消息失败: {e.SocketError.ToString()}, 即将断开连接。{e.BytesTransferred}|{e.SocketError}");
                Disconnect(e);
            }
        }
示例#7
0
        /// <summary>
        /// 反序列化
        /// <see cref="Serialize"/>
        /// </summary>
        public void Deserialize(ArrayPool <RpcValue> rpcValueArrayPool
                                , ObjectPool <RpcValue> rpcValuePool
                                , byte[] buffer
                                , ref int offset
                                , bool enableDeserializeValueType = true)
        {
            if (enableDeserializeValueType)
            {
                ValueType = (ValueType)buffer[offset];
                offset++;
            }

            switch (ValueType)
            {
            case ValueType.Byte:
                ByteValue = buffer[offset];
                offset++;
                break;

            case ValueType.Short:
                ShortValue = BitConverter.ToInt16(buffer, offset);
                offset    += sizeof(short);
                break;

            case ValueType.Int:
                IntValue = BitConverter.ToInt32(buffer, offset);
                offset  += sizeof(int);
                break;

            case ValueType.Long:
                LongValue = BitConverter.ToInt64(buffer, offset);
                offset   += sizeof(long);
                break;

            case ValueType.Float:
                FloatValue = BitConverter.ToSingle(buffer, offset);
                offset    += sizeof(float);
                break;

            case ValueType.Double:
                DoubleValue = BitConverter.ToDouble(buffer, offset);
                offset     += sizeof(double);
                break;

            case ValueType.FixedValueTypeArray:
            {
                int elementCount = BitConverter.ToInt32(buffer, offset);
                offset += sizeof(int);

                ValueType elementValueType = (ValueType)buffer[offset];
                offset++;
                ArrayValue = rpcValueArrayPool.AllocBuffer(elementCount);
                int        endPoint = ArrayValue.GetOffset() + ArrayValue.GetSize();
                RpcValue[] elements = ArrayValue.GetBuffer();
                for (int iElement = ArrayValue.GetOffset(); iElement < endPoint; iElement++)
                {
                    RpcValue iterElement = rpcValuePool.Alloc();
                    elements[iElement] = iterElement;

                    iterElement.ValueType = elementValueType;
                    iterElement.Deserialize(rpcValueArrayPool
                                            , rpcValuePool
                                            , buffer
                                            , ref offset
                                            , false);
                }
            }
            break;

            case ValueType.VariableValueTypeArray:
            {
                int elementCount = BitConverter.ToInt32(buffer, offset);
                offset += sizeof(int);

                ArrayValue = rpcValueArrayPool.AllocBuffer(elementCount);
                int        endPoint = ArrayValue.GetOffset() + ArrayValue.GetSize();
                RpcValue[] elements = ArrayValue.GetBuffer();
                for (int iElement = ArrayValue.GetOffset(); iElement < endPoint; iElement++)
                {
                    RpcValue iterElement = rpcValuePool.Alloc();
                    elements[iElement] = iterElement;

                    iterElement.Deserialize(rpcValueArrayPool
                                            , rpcValuePool
                                            , buffer
                                            , ref offset);
                }
            }
            break;

            default:
                throw new Exception("Not support ValueType: " + ValueType);
            }
        }
示例#8
0
        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="buffer">目标Buffer</param>
        /// <param name="offset">写入位置</param>
        /// <param name="enableSerializeValueType">
        /// 是否序列化<see cref="ValueType"/>
        /// 需要这个开关是因为序列化<see cref="ValueType.FixedValueTypeArray"/>时,不需要序列化数组中每个元素的<see cref="ValueType"/>
        /// </param>
        public void Serialize(byte[] buffer
                              , ref int offset
                              , bool enableSerializeValueType = true)
        {
            if (enableSerializeValueType)
            {
                MBitConverter.WriteTo(buffer, ref offset, (byte)ValueType);
            }

            switch (ValueType)
            {
            case ValueType.Byte:
                MBitConverter.WriteTo(buffer, ref offset, ByteValue);
                break;

            case ValueType.Short:
                MBitConverter.WriteTo(buffer, ref offset, ShortValue);
                break;

            case ValueType.Int:
                MBitConverter.WriteTo(buffer, ref offset, IntValue);
                break;

            case ValueType.Long:
                MBitConverter.WriteTo(buffer, ref offset, LongValue);
                break;

            case ValueType.Float:
                MBitConverter.WriteTo(buffer, ref offset, FloatValue);
                break;

            case ValueType.Double:
                MBitConverter.WriteTo(buffer, ref offset, DoubleValue);
                break;

            case ValueType.FixedValueTypeArray:
            {
                int elementCount = ArrayValue.GetSize();
                MBitConverter.WriteTo(buffer, ref offset, elementCount);
                MDebug.Assert(elementCount > 0
                              , "Rpc"
                              , "elementCount > 0");

                int        startPoint       = ArrayValue.GetOffset();
                int        endPoint         = startPoint + elementCount;
                RpcValue[] elements         = ArrayValue.GetBuffer();
                ValueType  elementValueType = elements[startPoint].ValueType;
                MBitConverter.WriteTo(buffer, ref offset, (byte)elementValueType);
                for (int iElement = startPoint; iElement < endPoint; iElement++)
                {
                    RpcValue iterElement = elements[iElement];
#if GF_DEBUG
                    MDebug.Assert(iterElement.ValueType == elementValueType
                                  , "Rpc"
                                  , "iterElement.ValueType == elementValueType");
#endif
                    iterElement.Serialize(buffer, ref offset, false);
                }
            }
            break;

            case ValueType.VariableValueTypeArray:
            {
                int elementCount = ArrayValue.GetSize();
                MBitConverter.WriteTo(buffer, ref offset, elementCount);
                MDebug.Assert(elementCount > 0
                              , "Rpc"
                              , "elementCount > 0");

                int        startPoint = ArrayValue.GetOffset();
                int        endPoint   = startPoint + elementCount;
                RpcValue[] elements   = ArrayValue.GetBuffer();
                for (int iElement = startPoint; iElement < endPoint; iElement++)
                {
                    RpcValue iterElement = elements[iElement];
                    iterElement.Serialize(buffer, ref offset);
                }
            }
            break;

            default:
                throw new Exception("Not support ValueType: " + ValueType);
            }
        }