예제 #1
0
        protected internal void ProcessReceive(SocketAsyncEventArgs e, SocketResult result)
        {
            var    userToken = e.UserToken as UserToken;
            Socket s         = userToken.ConnectSocket;

            try
            {
                result.Length           = e.BytesTransferred;
                result.ReceiveAvailable = s.Available > 0;
                if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
                {
                    result.Data = new byte[e.BytesTransferred];
                    Array.Copy(e.Buffer, e.Offset, result.Data, 0, result.Data.Length);
                    Array.Clear(e.Buffer, e.Offset, result.Data.Length);
                }
                userToken.SetResult(result);
            }
            catch (Exception ex)
            {
                userToken.SetException(ex);
            }
            finally
            {
                RecycleToken(userToken);
            }
        }
예제 #2
0
        protected void OnIOCompleted(object serder, SocketAsyncEventArgs e)
        {
            SocketResult result = new SocketResult {
                SocketError = e.SocketError, Args = e
            };

            switch (e.LastOperation)
            {
            case SocketAsyncOperation.Connect:
                ProcessConnect(e, result);
                break;

            case SocketAsyncOperation.Receive:
                ProcessReceive(e, result);
                break;

            case SocketAsyncOperation.Send:
                ProcessSend(e, result);
                break;

            case SocketAsyncOperation.SendPackets:
                ProcessSendPackets(e, result);
                break;

            case SocketAsyncOperation.Disconnect:
                ProcessDisconnect(e, result);
                break;

            default:
                throw new ArgumentException("The last operation completed on the socket was not a receive or send");
            }
        }
예제 #3
0
        public void SetResult(SocketResult result)
        {
            if (completionSource.Task.IsCompleted)
            {
                return;
            }
            completionSource.SetResult(result);
            timer.Change(Timeout.Infinite, Timeout.Infinite);
#if DEBUG
            Console.WriteLine($"UserToken SetResult: {Id} TaskID: {completionSource.Task.Id}");
#endif
        }
예제 #4
0
        public static Task <SocketResult> ReceiveAsync(this Socket socket, IOCPBase iocpBase, UserToken userToken)
        {
            var task = userToken.CompletionSource;

            if (!socket.ReceiveAsync(userToken.ReceiveArgs))
            {
                SocketResult result = new SocketResult {
                    SocketError = userToken.ReceiveArgs.SocketError, Args = userToken.ReceiveArgs
                };
                iocpBase.ProcessReceive(userToken.ReceiveArgs, result);
            }
            return(task);
        }
예제 #5
0
        static Task <SocketResult> SendDataAsync(Socket socket, SendPacketsElement[] elements, IOCPBase iocpBase, UserToken userToken)
        {
            var task = userToken.CompletionSource;

            userToken.ReceiveArgs.SendPacketsElements = elements;
            userToken.ReceiveArgs.SendPacketsFlags    = TransmitFileOptions.UseKernelApc;
            if (!socket.SendPacketsAsync(userToken.ReceiveArgs))
            {
                SocketResult result = new SocketResult {
                    SocketError = userToken.ReceiveArgs.SocketError, Args = userToken.ReceiveArgs
                };
                iocpBase.ProcessSendPackets(userToken.ReceiveArgs, result);
            }
            return(task);
        }
예제 #6
0
        protected internal void ProcessDisconnect(SocketAsyncEventArgs e, SocketResult result)
        {
            var userToken = e.UserToken as UserToken;

            try
            {
                userToken.SetResult(result);
            }
            catch (Exception ex)
            {
                userToken.SetException(ex);
            }
            finally
            {
                RecycleToken(userToken);
            }
        }
예제 #7
0
        protected internal void ProcessSendPackets(SocketAsyncEventArgs e, SocketResult result)
        {
            var userToken = e.UserToken as UserToken;

            try
            {
                userToken.SetResult(result);
            }
            catch (Exception ex)
            {
                userToken.SetException(ex);
            }
            finally
            {
                userToken.ReceiveArgs.SendPacketsElements = null;
                userToken.ReceiveArgs.SendPacketsFlags    = TransmitFileOptions.UseDefaultWorkerThread;
                RecycleToken(userToken);
            }
        }
예제 #8
0
        public static Task <SocketResult> SendAsync(this Socket socket, byte[] data, IOCPBase iocpBase, UserToken userToken)
        {
            if (data.Length > iocpBase.BufferSize)
            {
                SendPacketsElement[] elements = new SendPacketsElement[1];
                elements[0] = new SendPacketsElement(data, 0, data.Length, true);
                return(SendDataAsync(socket, elements, iocpBase, userToken));
            }
            var task = userToken.CompletionSource;

            Array.Copy(data, 0, userToken.ReceiveArgs.Buffer, userToken.ReceiveArgs.Offset, data.Length);
            userToken.ReceiveArgs.SetBuffer(userToken.ReceiveArgs.Offset, data.Length);
            if (!socket.SendAsync(userToken.ReceiveArgs))
            {
                SocketResult result = new SocketResult {
                    SocketError = userToken.ReceiveArgs.SocketError, Args = userToken.ReceiveArgs
                };
                iocpBase.ProcessSend(userToken.ReceiveArgs, result);
            }
            return(task);
        }