Exemple #1
0
        private void OperationCompleted(object o, SocketAsyncEventArgs args)
        {
            if (args.SocketError != SocketError.Success || (args.LastOperation == SocketAsyncOperation.Receive && args.BytesTransferred == 0))
            {
                OnError?.Invoke(args);
            }
            else
            {
                var data = args.GetUserToken <BufferData>();

                switch (args.LastOperation)
                {
                case SocketAsyncOperation.Send:
                    data.ByteCount += args.BytesTransferred;

                    // We've transferred less bytes than we should have
                    if (data.Length > data.ByteCount)
                    {
                        args.SetBuffer(data.BaseOffset + data.ByteCount, data.Length - data.ByteCount);

                        // TODO: test if multiple send operations will collide (if the packet was only sent partially, and another packet is getting sent between the two parts)
                        // TODO: create a queue for sending async, if it collides?
                        SendAsync(args);
                        return;
                    }

                    OnSend?.Invoke(args);
                    break;

                case SocketAsyncOperation.Receive:
                    // This value may change in the middle of processing, causing odd behavior
                    var receiveAfter = AutoReceive;
                    if (ProcessInputBuffer(data, args))
                    {
                        return;
                    }

                    if (receiveAfter)
                    {
                        ReceiveAsync();
                    }

                    break;

                case SocketAsyncOperation.Connect:
                    OnConnect?.Invoke(args);
                    break;

                case SocketAsyncOperation.Accept:
                    OnAccept?.Invoke(new LengthedSocket(args.AcceptSocket, SizeHeaderLength, CountSize));
                    break;
                }
            }

            TeardownEventArgs(args);
        }
Exemple #2
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);
        }