public void CanWeClearBufferContent()
        {
            var settings = CreateSettings(1, 10, 1);
            var manager = new BufferManager(settings);
            byte[] test = manager.GetBuffer(10);
            test[0] = 0x01;
            Assert.NotNull(test);
            Assert.AreEqual(test.Length, 10); //we get the same length

            manager.FreeBuffer(ref test, true);

            test = manager.GetBuffer(10);
            Assert.True(test[0] == 0x00);//we got a cleared one
        }
        public void CanWeAllocateBuffers()
        {
            var settings = CreateSettings(1, 10, 1);
            var manager = new BufferManager(settings);
            byte[] test = manager.GetBuffer(10);
            test[0] = 0x01;
            Assert.NotNull(test);
            Assert.AreEqual(test.Length, 10); //we get the same length

            manager.FreeBuffer(ref test);

            Assert.True(test == BufferManager.EmptyBuffer); //we aren't referencing it anymore

            test = manager.GetBuffer(10);
            Assert.True(test[0] == 0x01);//we got the same one back
        }
Ejemplo n.º 3
0
        public void Write(ProtocolBufferWriter writer)
        {
            writer.WriteULong(EntityId);

            switch (Subtype)
            {
            case CallMethodMessageSubtype.MethodId:
            case CallMethodMessageSubtype.UnkPlusMethodId:
                writer.WriteUInt((uint)MethodId);
                break;

            case CallMethodMessageSubtype.MethodName:
            case CallMethodMessageSubtype.UnkPlusMethodName:
                writer.WriteString(MethodName);
                break;

            default:
                throw new Exception($"Invalid subtype ({Subtype}) for CallMethodMessage!");
            }

            var buffer = BufferManager.RequestBuffer();

            using (var bw = buffer.CreateWriter())
            {
                bw.Write((byte)0x4F);  // 'O' - Optimized Marshall Format

                Packet.Write(bw);

                bw.Write((byte)0x66);  // 'f' - python payload finish mark

                writer.WriteArray(buffer.Buffer, buffer.BaseOffset, (int)bw.BaseStream.Position);
            }

            BufferManager.FreeBuffer(buffer);

            if (Subtype == CallMethodMessageSubtype.UnkPlusMethodId || Subtype == CallMethodMessageSubtype.UnkPlusMethodName)
            {
                writer.WriteUInt(UnknownValue);
            }
        }
Ejemplo n.º 4
0
        private void TeardownEventArgs(SocketAsyncEventArgs args)
        {
            switch (args.LastOperation)
            {
            case SocketAsyncOperation.Receive:
            case SocketAsyncOperation.Send:
                BufferManager.FreeBuffer(args.GetUserToken <BufferData>());

                args.SetBuffer(null, 0, 0);
                args.UserToken = null;
                break;

            case SocketAsyncOperation.Connect:
                args.RemoteEndPoint = null;
                break;
            }

            args.AcceptSocket = null;
            args.Completed   -= OperationCompleted;

            lock (_socketAsyncEventArgsPool)
                _socketAsyncEventArgsPool.Push(args);
        }
Ejemplo n.º 5
0
        public void Read(BinaryReader br)
        {
            if (br.BaseStream.Length < 4)
            {
                throw new Exception("Fragmented receive, should not happen! (4 size header)");
            }

            Size    = br.ReadUInt16();
            Channel = br.ReadByte();

            br.ReadByte(); // padding

            if (Size > br.BaseStream.Length)
            {
                Debugger.Break();

                throw new Exception($"Fragmented receive, should not happen! Packet size: {Size} <-> Buffer length: {br.BaseStream.Length}");
            }

            if (Channel == 0xFF) // Internal channel: Send timeout checking, ignore the packet
            {
                return;
            }

            if (Channel != 0)                     // 0 == ReliableStreamChannel (no extra data), Move message uses channels
            {
                SequenceNumber = br.ReadUInt32(); // Sequence number? if (previousValue - newValue < 0) { process packet; previousValue = newValue; }
                br.ReadInt32();                   // 0xDEADBEEF
                br.ReadInt32();                   // skip
            }

            var packetBeginPosition = br.BaseStream.Position;

            using (var reader = new ProtocolBufferReader(br, ProtocolBufferFlags.DontFragment))
            {
                reader.ReadProtocolFlags();


                reader.ReadPacketType(out ushort type, out bool compress);

                Type     = (ClientMessageOpcode)type;
                Compress = compress;

                reader.ReadXORCheck((int)(br.BaseStream.Position - packetBeginPosition));
            }

            var xorCheckPosition = (int)br.BaseStream.Position;

            var readBr = br;

            BufferData buffer = null;

            if (Compress)
            {
                var someType = br.ReadByte(); // 0 = No compression
                if (someType >= 2)
                {
                    throw new Exception("Invalid compress type received!");
                }

                if (someType == 1)
                {
                    Debugger.Break(); // TODO: test

                    var uncompressedSize = br.ReadInt32();

                    byte[] uncompressedData;
                    var    offset = 0;

                    if (uncompressedSize > BufferManager.BlockSize)
                    {
                        uncompressedData = new byte[uncompressedSize];
                    }
                    else
                    {
                        buffer = BufferManager.RequestBuffer();

                        uncompressedData = buffer.Buffer;
                        offset           = buffer.BaseOffset;
                    }

                    using (var deflateStream = new DeflateStream(br.BaseStream, CompressionMode.Decompress, true)) // TODO: test if the br.BaseStream is cool as the Stream input for the DeflateStream
                        deflateStream.Read(uncompressedData, offset, uncompressedSize);

                    readBr = buffer != null?buffer.GetReader() : new BinaryReader(new MemoryStream(uncompressedData, 0, uncompressedSize, false), Encoding.UTF8, false);
                }
            }

            // ReSharper disable SwitchStatementMissingSomeCases
            switch (Type)
            {
            case ClientMessageOpcode.Login:
                Message = new LoginMessage();
                break;

            case ClientMessageOpcode.Move:
                Message = new MoveMessage();
                break;

            case ClientMessageOpcode.CallServerMethod:
                Message = new CallServerMethodMessage();
                break;

            case ClientMessageOpcode.Ping:
                Message = new PingMessage();
                break;

            default:
                throw new Exception($"Unable to handle packet type {Type}, because it's a Server -> Client packet!");
            }
            // ReSharper restore SwitchStatementMissingSomeCases

            using (var reader = new ProtocolBufferReader(readBr, ProtocolBufferFlags.DontFragment))
            {
                reader.ReadProtocolFlags();

                // Subtype and Message.Read()
                reader.ReadDebugByte(41);

                if ((Message.SubtypeFlags & ClientMessageSubtypeFlag.HasSubtype) == ClientMessageSubtypeFlag.HasSubtype)
                {
                    Message.RawSubtype = reader.ReadByte();
                    if (Message.RawSubtype < Message.MinSubtype || Message.RawSubtype > Message.MaxSubtype)
                    {
                        throw new Exception("Invalid Subtype found!");
                    }
                }

                Message.Read(reader);

                reader.ReadDebugByte(42);

                reader.ReadXORCheck((int)br.BaseStream.Position - xorCheckPosition);
            }

            if (buffer != null) // If we requested a buffer for decompressing, free it
            {
                BufferManager.FreeBuffer(buffer);
            }
        }
Ejemplo n.º 6
0
        public void Write(BinaryWriter bw)
        {
            var sizePosition = bw.BaseStream.Position;

            bw.Write((ushort)0);  // Size placeholder

            bw.Write(Channel);
            bw.Write((byte)0);  // padding

            if (Channel != 0)
            {
                bw.Write(SequenceNumber); // sequence num?
                bw.Write(0xDEADBEEF);     // const
                bw.Write(0);              // padding
            }

            var packetBeginPosition = (int)bw.BaseStream.Position;

            var packetBuffer = BufferManager.RequestBuffer();
            int uncompressedSize;

            using (var ms = new MemoryStream(packetBuffer.Buffer, packetBuffer.BaseOffset, packetBuffer.MaxLength, true))
            {
                using (var packetWriter = new BinaryWriter(ms, Encoding.UTF8, true))
                {
                    using (var writer = new ProtocolBufferWriter(packetWriter, ProtocolBufferFlags.DontFragment))
                    {
                        writer.WriteProtocolFlags();

                        writer.WriteDebugByte(41);

                        if ((Message.SubtypeFlags & ClientMessageSubtypeFlag.HasSubtype) == ClientMessageSubtypeFlag.HasSubtype)
                        {
                            writer.WriteByte(Message.RawSubtype);
                        }

                        Message.Write(writer);

                        writer.WriteDebugByte(42);

                        var currentPos = (int)ms.Position;

                        writer.WriteXORCheck(currentPos);

                        uncompressedSize = (int)ms.Position;
                    }
                }
            }

            var compress = (Message.SubtypeFlags & ClientMessageSubtypeFlag.Compress) == ClientMessageSubtypeFlag.Compress && uncompressedSize > 0;

            using (var writer = new ProtocolBufferWriter(bw, ProtocolBufferFlags.DontFragment))
            {
                writer.WriteProtocolFlags();

                writer.WritePacketType((ushort)Message.Type, compress);

                writer.WriteXORCheck((int)(bw.BaseStream.Position - packetBeginPosition));
            }

            int packetSize = uncompressedSize;

            if (compress) // TODO: test
            {
                bw.Write((byte)0x01);
                bw.Write(uncompressedSize);

                var compressedBuffer = BufferManager.RequestBuffer();
                int compressedSize;

                using (var compressStream = compressedBuffer.GetStream(true))
                {
                    using (var compressorStream = new DeflateStream(compressStream, CompressionMode.Compress, true))
                        compressorStream.Write(packetBuffer.Buffer, packetBuffer.BaseOffset, uncompressedSize);

                    compressedSize = (int)compressStream.Position;
                }

                BufferManager.FreeBuffer(packetBuffer);

                packetBuffer = compressedBuffer;
                packetSize   = compressedSize;
            }

            bw.Write(packetBuffer.Buffer, packetBuffer.BaseOffset, packetSize);

            BufferManager.FreeBuffer(packetBuffer);

            var currentPosition = bw.BaseStream.Position;

            bw.BaseStream.Position = sizePosition;

            bw.Write((ushort)(currentPosition - sizePosition));

            bw.BaseStream.Position = currentPosition;
        }
Ejemplo n.º 7
0
 public void RemoveSession(Session session)
 {
     _bufferManager.FreeBuffer(session.ReadEventArg);
 }
Ejemplo n.º 8
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            //TimeSpan timeout = new TimeSpan(0, 0, 0, 5, 0);
            TimeSpan      timeout       = TimeSpan.FromMinutes(10);
            BufferManager bufferManager = new BufferManager(100 * 1024 * 2, 1024);

            bufferManager.InitBuffer();

            while (!stoppingToken.IsCancellationRequested)
            {
                using TcpClient _tcpClient = new TcpClient();

                AsyncUserToken asyncUserToken = new AsyncUserToken();

                using SocketAsyncEventArgs sendArg   = new SocketAsyncEventArgs();
                using SocketAsyncEventArgs reciveArg = new SocketAsyncEventArgs();
                reciveArg.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                reciveArg.UserToken  = asyncUserToken;
                bufferManager.SetBuffer(reciveArg);

                try
                {
                    _logger.LogInformation("连接");
                    await _tcpClient.ConnectAsync(hostname, port, stoppingToken);

                    _logger.LogInformation("已连接");
                    NetworkStream ns = _tcpClient.GetStream();
                    asyncUserToken.Socket = _tcpClient.Client;

                    for (int i = 0; i < 1000; i++)
                    {
                        try
                        {
                            DateTime startTime = DateTime.Now;
                            if (_tcpClient.Connected == false) // 断线重连
                            {
                                await _tcpClient.ConnectAsync(hostname, port);

                                ns = _tcpClient.GetStream();
                                asyncUserToken.Socket = _tcpClient.Client;
                            }

                            #region write

                            string msg = $"{Thread.CurrentThread.ManagedThreadId} >> {Guid.NewGuid():n} >> {DateTime.Now}";
                            _logger.LogInformation($"请求:\n\t{msg}\n");

                            byte[] requestBuffer = Encoding.UTF8.GetBytes(msg);
                            sendArg.SetBuffer(requestBuffer);
                            _tcpClient.Client.SendAsync(sendArg);
                            #endregion

                            #region read
                            using CancellationTokenSource cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken);
                            cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(3));

                            using (cancellationTokenSource.Token.Register(() => _waitLock.Set()))
                            {
                                _waitLock.WaitOne();
                            }

                            byte[] data = null;
                            lock (asyncUserToken.Buffer)
                            {
                                data = asyncUserToken.Buffer.ToArray();
                                asyncUserToken.Buffer.Clear();
                            }
                            if (data != null && data.Length > 0)
                            {
                                _logger.LogInformation($"响应:\n\t{Encoding.UTF8.GetString(data)}\n");
                            }
                            #endregion

                            _logger.LogInformation($"\n耗时: {DateTime.Now - startTime}\n");
                            // await Task.Delay(1000, stoppingToken);
                            await Task.Delay(0, stoppingToken);

                            //await Task.Delay(TimeSpan.FromMinutes(10));
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, ex.Message);
                            await Task.Delay(5000, stoppingToken);
                        }
                    }
                }
                catch (TaskCanceledException)
                {
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, ex.Message);
                }
                finally
                {
                    bufferManager.FreeBuffer(reciveArg);
                    _logger.LogInformation("断开连接");
                    _tcpClient?.Close();
                    _tcpClient?.Dispose();

                    _logger.LogInformation("已断开连接");
                }

                await Task.Delay(2000, stoppingToken);
            }
        }
Ejemplo n.º 9
0
        public void Send(string connectionId, byte[] buffer)
        {
            AsyncUserToken token;

            //SocketAsyncEventArgs token;

            //if (buffer.Length <= m_receiveSendBufferSize)
            //{
            //    throw new ArgumentException("数据包长度超过缓冲区大小", "buffer");
            //}

            lock (((ICollection)this.m_tokens).SyncRoot)
            {
                if (!this.m_tokens.TryGetValue(connectionId, out token))
                {
                    throw new AsyncSocketException(string.Format("客户端:{0}已经关闭或者未连接", connectionId), AsyncSocketErrorCode.ClientSocketNoExist);

                    //return;
                }
            }
            SocketAsyncEventArgs writeEventArgs;

            lock (m_writePool)
            {
                writeEventArgs = m_writePool.Pop();// 分配一个写SocketAsyncEventArgs对象
            }
            writeEventArgs.UserToken = token;
            if (buffer.Length <= m_BufferSize)
            {
                Array.Copy(buffer, 0, writeEventArgs.Buffer, writeEventArgs.Offset, buffer.Length);
                writeEventArgs.SetBuffer(writeEventArgs.Buffer, writeEventArgs.Offset, buffer.Length);
            }
            else
            {
                lock (m_bufferLock)
                {
                    m_bufferManager.FreeBuffer(writeEventArgs);
                }
                writeEventArgs.SetBuffer(buffer, 0, buffer.Length);
            }

            //writeEventArgs.SetBuffer(buffer, 0, buffer.Length);
            try
            {
                // 异步发送数据
                bool willRaiseEvent = token.Socket.SendAsync(writeEventArgs);
                if (!willRaiseEvent)
                {
                    ProcessSend(writeEventArgs);
                }
            }
            catch (ObjectDisposedException)
            {
                RaiseDisconnectedEvent(token);
            }
            catch (SocketException socketException)
            {
                if (socketException.ErrorCode == (int)SocketError.ConnectionReset) //10054一个建立的连接被远程主机强行关闭
                {
                    RaiseDisconnectedEvent(token);                                 //引发断开连接事件
                }
                else
                {
                    RaiseErrorEvent(token, new AsyncSocketException("在SocketAsyncEventArgs对象上执行异步发送数据操作时发生SocketException异常", socketException));;
                }
            }
            catch (Exception exception_debug)
            {
                Debug.WriteLine("调试:" + exception_debug.Message);
                throw exception_debug;
            }
        }
Ejemplo n.º 10
0
 private void Clear(BufferManager buffermanager)
 {
     buffermanager.FreeBuffer(_ReadAsyncEventArgs);
 }