コード例 #1
0
 private async Task StartConnecting(ClientStateObject state)
 {
     var args = new SocketAsyncEventArgs() { RemoteEndPoint = _endpoint };
     var awaitable = new SocketAwaitable(args);
     await state.WorkSocket.ConnectAsync(awaitable);
     await StartSending(state);
 }
コード例 #2
0
        private async Task StartReceiving(StateObject state)
        {
            if (_isDisposed) return;
            if (!_socket.Connected) return;

            _logger.Info("Receiving message...");

            var args = new SocketAsyncEventArgs();
            args.SetBuffer(new byte[0x1000], 0, 0x1000);
            var awaitable = new SocketAwaitable(args);

            while (true)
            {
                await _socket.ReceiveAsync(awaitable);
                var bytesRead = args.BytesTransferred;
                if (bytesRead <= 0) break;

                _logger.Info(string.Format("Bytes read: {0}", bytesRead));
                if (awaitable.EventArgs.Buffer[0] == _framingProtocol.StartFrame || state.StartedReceiving)
                {
                    state.Append(Encoding.ASCII.GetString(awaitable.EventArgs.Buffer, 0, bytesRead));
                }

                if (awaitable.EventArgs.Buffer[bytesRead - 1] == _framingProtocol.EndFrame) // We're done
                {
                    InvokeMessageReceived(state.ToString());
                }
            }
        }
コード例 #3
0
 public static SocketAwaitable SendAsync(this Socket socket, SocketAwaitable awaitable)
 {
     awaitable.Reset();
     if (!socket.SendAsync(awaitable.EventArgs))
         awaitable.WasCompleted = true;
     return awaitable;
 }
コード例 #4
0
 public static SocketAwaitable ReceiveAsync(this Socket socket, SocketAwaitable awaitable)
 {
     awaitable.Reset();
     if (!socket.ReceiveAsync(awaitable.m_eventArgs))
         awaitable.m_wasCompleted = true;
     return awaitable;
 }
コード例 #5
0
        public void TestConcurrentAccess()
        {
            int count = 20;

            // Initialize using a specific count.
            var pool = new SocketAwaitablePool(count);
            Assert.AreEqual(pool.Count, count);

            // Deplete the pool.
            Parallel.For(0, count, i => Assert.IsNotNull(pool.Take()));
            Assert.AreEqual(pool.Count, 0);

            // Force pool to initialize new awaitables.
            var newAwaitables = new SocketAwaitable[count];
            Parallel.For(0, count, i => Assert.IsNotNull(newAwaitables[i] = pool.Take()));

            // Add new awaitables [back] to the pool.
            Parallel.For(0, count, i => pool.Add(newAwaitables[i]));
            Assert.AreEqual(pool.Count, count);

            // Add to, take from and iterate the pool in parallel.
            var addTask = Task.Run(
                () => Parallel.For(0, 1000000, i => pool.Add(new SocketAwaitable())));

            var takeTask = Task.Run(
                () => Parallel.For(0, 1000000 + count, i => Assert.IsNotNull(pool.Take())));

            var iterateTask = Task.Run(
                () => Parallel.ForEach(pool, e => Assert.IsNotNull(e)));

            Task.WaitAll(addTask, takeTask, iterateTask);
        }
コード例 #6
0
        public static IAwaitable SendAsync(this Socket socket, byte[] buffer)
        {
            var args = new SocketAsyncEventArgs();

            args.SetBuffer(buffer);
            var awaitable = new SocketAwaitable(args);

            return(socket.SendAsync(awaitable));
        }
コード例 #7
0
 /// <summary>
 /// Sends data asynchronously to a connected <see cref="Socket"/> object using await.
 /// </summary>
 /// <param name="socket">The connected <see cref="Socket"/> object to use.</param>
 /// <param name="awaitable">The <see cref="SocketAwaitable"/> to await on.</param>
 /// <returns>A <see cref="SocketAwaitable"/> object ready to be reused.</returns>
 public static SocketAwaitable SendAsync(this Socket socket, SocketAwaitable awaitable)
 {
     awaitable.Reset();
     if (!socket.SendAsync(awaitable.EventArgs))
     {
         awaitable.IsCompleted = true;
     }
     return(awaitable);
 }
コード例 #8
0
        /// <summary>
        /// Begins an asynchronous to disconnect from a remote host using await.
        /// </summary>
        /// <param name="socket">The connected <see cref="Socket"/> object to use.</param>
        /// <param name="awaitable">The <see cref="SocketAwaitable"/> to await on.</param>
        /// <returns>A <see cref="SocketAwaitable"/> object ready to be reused.</returns>
        public static SocketAwaitable DisconnectAsync(this Socket socket, SocketAwaitable awaitable)
        {
            awaitable.Reset();

            socket.Dispose();
            awaitable.IsCompleted = true;

            return(awaitable);
        }
コード例 #9
0
 public static SocketAwaitable SendToAsync(this Socket socket, SocketAwaitable awaitable)
 {
     awaitable.Reset();
     if (!socket.SendToAsync(awaitable.m_eventArgs))
     {
         awaitable.m_wasCompleted = true;
     }
     return awaitable;
 }
コード例 #10
0
        public void TestDisposing()
        {
            var awaitable = new SocketAwaitable();

            Assert.IsFalse(awaitable.IsDisposed);

            awaitable.Dispose();
            Assert.IsTrue(awaitable.IsDisposed);
        }
コード例 #11
0
        public SocketByteHandler(Socket socket)
        {
            m_socket = socket;
            var socketEventArgs = new SocketAsyncEventArgs();

            m_socketAwaitable = new SocketAwaitable(socketEventArgs);
            m_closeSocket     = socket.Dispose;
            RemainingTimeout  = Constants.InfiniteTimeout;
        }
コード例 #12
0
        public PacketTransmitter(Socket socket)
        {
            m_socket = socket;
            var socketEventArgs = new SocketAsyncEventArgs();

            m_buffer = new byte[4096];
            socketEventArgs.SetBuffer(m_buffer, 0, 0);
            m_socketAwaitable = new SocketAwaitable(socketEventArgs);
        }
コード例 #13
0
 /// <summary>
 /// Begins an asynchronous to disconnect from a remote host using await.
 /// </summary>
 /// <param name="socket">The connected <see cref="Socket"/> object to use.</param>
 /// <param name="awaitable">The <see cref="SocketAwaitable"/> to await on.</param>
 /// <returns>A <see cref="SocketAwaitable"/> object ready to be reused.</returns>
 public static SocketAwaitable DisconnectAsync(this Socket socket, SocketAwaitable awaitable)
 {
     awaitable.Reset();
     if (!socket.DisconnectAsync(awaitable.EventArgs))
     {
         awaitable.IsCompleted = true;
     }
     return awaitable;
 }
コード例 #14
0
 /// <summary>
 /// Begins an asynchronous to a connection to a remote host using await.
 /// </summary>
 /// <param name="socket">The connected <see cref="Socket"/> object to use.</param>
 /// <param name="awaitable">The <see cref="SocketAwaitable"/> to await on.</param>
 /// <returns>A <see cref="SocketAwaitable"/> object ready to be reused.</returns>
 public static SocketAwaitable ConnectAsync(this Socket socket, SocketAwaitable awaitable)
 {
     awaitable.Reset();
     if (!socket.ConnectAsync(awaitable.EventArgs))
     {
         awaitable.IsCompleted = true;
     }
     return awaitable;
 }
コード例 #15
0
        /// <summary>
        /// Creates a proper awaitable async receive object.
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="awaitable"></param>
        /// <returns></returns>
        internal static SocketAwaitable ReceiveAsync(this Socket socket,
            SocketAwaitable awaitable)
        {
            awaitable.Reset();

            if (!socket.ReceiveAsync(awaitable.pEventArgs))
                awaitable.pWasCompleted = true;

            return awaitable;
        }
コード例 #16
0
        public Listener(
            ListenerSettings settings,
            Func<Socket, IWorker> createWorker)
        {
            _settings = settings;
            _createWorker = createWorker;

            // create awaitable
            _awaitable = new SocketAwaitable(Timeout.InfiniteTimeSpan);
        }
コード例 #17
0
 private static SocketAwaitable ReceiveAsync(this Socket socket,
                                             SocketAwaitable awaitable)
 {
     awaitable.Reset();
     if (!socket.ReceiveAsync(awaitable.EventArgs))
     {
         awaitable.IsCompleted = true;
     }
     return(awaitable);
 }
コード例 #18
0
 /// <summary>
 /// Begins an asynchronous request to receive data from a connected <see cref="Socket"/> object using await.
 /// </summary>
 /// <param name="awaitable">The <see cref="SocketAwaitable"/> to await on.</param>
 /// <returns>A <see cref="SocketAwaitable"/> object ready to be reused.</returns>
 public static SocketAwaitable ReceiveAsync(this SocketAwaitable awaitable)
 {
     awaitable.Reset();
     var socket = awaitable.EventArgs.AcceptSocket;
     if (!socket.ReceiveAsync(awaitable.EventArgs))
     {
         awaitable.IsCompleted = true;
     }
     return awaitable;
 }
コード例 #19
0
        public async Task <byte[]> ReadBytesAsync(int count)
        {
            using (var awaitable = new SocketAwaitable())
            {
                awaitable.Buffer = new ArraySegment <byte>(new byte[count], 0, count);
                await this.socket.ReceiveAsync(awaitable);

                return(awaitable.Transferred.Array);
            }
        }
コード例 #20
0
 public static SocketAwaitable ReceiveAsync(this Socket socket,
                                            SocketAwaitable awaitable)
 {
     awaitable.Reset();
     if (!socket.ReceiveAsync(awaitable.m_eventArgs))
     {
         awaitable.m_wasCompleted = true;
     }
     return(awaitable);
 }
コード例 #21
0
        public void TestCopyingAfterDispose()
        {
            var pool = new SocketAwaitablePool(1);

            pool.Dispose();

            var array = new SocketAwaitable[1];

            (pool as ICollection).CopyTo(array, 0);
        }
コード例 #22
0
        public TcpMessagingClient()
        {
            _writeArgs      = new SocketAsyncEventArgs();
            _writeAwaitable = new SocketAwaitable(_writeArgs);

            _readArgs      = new SocketAsyncEventArgs();
            _readAwaitable = new SocketAwaitable(_readArgs);

            _encoder = new SimpleProtocolEncoder(_serializer);
            _decoder = new SimpleProtocolDecoder(_serializer);
        }
コード例 #23
0
        private Task StartReceiver(CancellationToken token)
        {
            return(Task.Run(async() =>
            {
                var args = new SocketAsyncEventArgs();
                args.SetBuffer(_readerBuffer, 0, _readerBuffer.Length);
                var awaitable = new SocketAwaitable(args);

                while (!token.IsCancellationRequested && _socket.IsConnected())
                {
                    try
                    {
                        if (_socket.Available == 0)
                        {
                            await Task.Delay(10, token);
                            continue;
                        }
                        await _socket.ReceiveAsync(awaitable);
                    }
                    catch (SocketException e)
                    {
                        Log.Debug(e);
                    }
                    if (args.SocketError != SocketError.Success)
                    {
                        break;
                    }
                    int bytesRead = args.BytesTransferred;
                    if (bytesRead <= 0)
                    {
                        break;
                    }

                    try
                    {
                        await ProcessReceivedDataAsync(new ArraySegment <byte>(_readerBuffer, 0, bytesRead));
                    }
                    catch (Exception e)
                    {
                        Log.Error(e, "Critical error while precessing received data.");
                        break;
                    }
                }
                try
                {
                    await DisconnectAsync();
                }
                catch (Exception e)
                {
                    Log.Debug(e);
                }
            }, token));
        }
コード例 #24
0
        public void TestInitialization()
        {
            // Default values.
            var awaitable = new SocketAwaitable();

            Assert.IsNull(awaitable.AcceptSocket);

            var awaiter = awaitable.GetAwaiter();

            Assert.IsTrue(awaiter.IsCompleted);
            Assert.AreEqual(awaiter.GetResult(), SocketError.Success);
        }
コード例 #25
0
        public static async Task SendAsync(this Socket socket, SocketAwaitable awaitable)
        {
            var isPending = socket.SendAsync(awaitable._eventArgs);

            if (!isPending)
            {
                return;
            }

            awaitable.Reset();
            await awaitable;
        }
コード例 #26
0
        private Task StartReceiver(CancellationToken token)
        {
            return(Task.Run(async() =>
            {
                var args = new SocketAsyncEventArgs();
                args.SetBuffer(_readerBuffer, 0, _readerBuffer.Length);
                var awaitable = new SocketAwaitable(args);
                while (!token.IsCancellationRequested && _socket.IsConnected())
                {
                    try
                    {
                        await _socket.ReceiveAsync(awaitable);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Error receiving: " + ex);
                        break;
                    }
                    if (args.SocketError != SocketError.Success)
                    {
                        break;
                    }
                    int bytesRead = args.BytesTransferred;
                    if (bytesRead <= 0)
                    {
                        break;
                    }

                    try
                    {
                        await ProcessReceivedDataAsync(new ArraySegment <byte>(_readerBuffer, 0, bytesRead));
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Critical error while precessing received data: " + e);
                        break;
                    }
                }
                try
                {
                    await DisconnectAsync();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
                if (_onDisconnectInternally != null)
                {
                    _onDisconnectInternally();
                }
            }, token));
        }
コード例 #27
0
        public async Task ConnectAsync(CancellationToken token)
        {
            ThrowIfDisposed();
            ThrowIfOnServerSide();
            using (await _stateAsyncLock.LockAsync(token))
            {
                if (State == ClientTransportState.Connected)
                {
                    return;
                }

                var args = new SocketAsyncEventArgs {
                    RemoteEndPoint = _remoteEndPoint
                };

                var awaitable = new SocketAwaitable(args);

                try
                {
                    _packetNumber = 0;
                    await _socket.ConnectAsync(awaitable);
                }
                catch (SocketException e)
                {
                    Console.WriteLine(e);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    _state = ClientTransportState.Disconnected;
                    throw;
                }

                switch (args.SocketError)
                {
                case SocketError.Success:
                case SocketError.IsConnected:
                    _state = ClientTransportState.Connected;
                    break;

                default:
                    _state = ClientTransportState.Disconnected;
                    break;
                }
                if (_state != ClientTransportState.Connected)
                {
                    return;
                }
                _connectionCancellationTokenSource = new CancellationTokenSource();
                _receiverTask = StartReceiver(_connectionCancellationTokenSource.Token);
            }
        }
コード例 #28
0
        public async Task <byte[]> ReadBytesAsync(int count)
        {
            using (var args = new SocketAsyncEventArgs())
            {
                args.SetBuffer(new byte[count], 0, count);
                var awaitable = new SocketAwaitable(args);
                await this.socket.ReceiveAsync(awaitable);

                var receivedBytes = new Byte[args.BytesTransferred];
                Buffer.BlockCopy(args.Buffer, 0, receivedBytes, 0, args.BytesTransferred);
                return(receivedBytes);
            }
        }
コード例 #29
0
ファイル: TcpTransport.cs プロジェクト: andri-ys/SharpMTProto
        public async Task SendAsync(byte[] payload, CancellationToken token)
        {
            await Task.Run(async() =>
            {
                var packet = new TcpTransportPacket(_packetNumber++, payload);

                var args = new SocketAsyncEventArgs();
                args.SetBuffer(packet.Data, 0, packet.Data.Length);

                var awaitable = new SocketAwaitable(args);
                await _socket.SendAsync(awaitable);
            }, token).ConfigureAwait(false);
        }
コード例 #30
0
        public async Task TestAwaiterStatus()
        {
            using (var listener = new Socket(SocketType.Stream, ProtocolType.Tcp))
            {
                listener.Bind(new IPEndPoint(IPAddress.IPv6Any, 0));
                listener.Listen(1);
                var acceptTask = Task.Run(async() =>
                {
                    using (var awaitable = new SocketAwaitable())
                    {
                        var awaiter = awaitable.GetAwaiter();
                        Assert.IsTrue(awaiter.IsCompleted);
                        Assert.AreEqual(awaiter.GetResult(), SocketError.Success);

                        var a = listener.AcceptAsync(awaitable);
                        Assert.IsFalse(awaiter.IsCompleted);
                        Assert.AreEqual(awaiter.GetResult(), SocketError.AlreadyInProgress);

                        var result = await a;
                        Assert.IsTrue(awaiter.IsCompleted);
                        Assert.AreEqual(awaiter.GetResult(), result);
                    }
                });

                await Task.Delay(500);

                using (var client = new Socket(SocketType.Stream, ProtocolType.Tcp))
                {
                    using (var awaitable = new SocketAwaitable())
                    {
                        awaitable.RemoteEndPoint = new IPEndPoint(
                            IPAddress.IPv6Loopback,
                            (listener.LocalEndPoint as IPEndPoint).Port);

                        var awaiter = awaitable.GetAwaiter();
                        Assert.IsTrue(awaiter.IsCompleted);
                        Assert.AreEqual(awaiter.GetResult(), SocketError.Success);

                        var a = client.ConnectAsync(awaitable);
                        Assert.IsFalse(awaiter.IsCompleted);
                        Assert.AreEqual(awaiter.GetResult(), SocketError.AlreadyInProgress);

                        var result = await a;
                        Assert.IsTrue(awaiter.IsCompleted);
                        Assert.AreEqual(awaiter.GetResult(), result);
                    }
                }

                await acceptTask;
            }
        }
コード例 #31
0
ファイル: TcpTransport.cs プロジェクト: andri-ys/SharpMTProto
        public async Task ConnectAsync(CancellationToken token)
        {
            using (await _stateAsyncLock.LockAsync(token))
            {
                if (State == TransportState.Connected)
                {
                    return;
                }

                var args = new SocketAsyncEventArgs {
                    RemoteEndPoint = new IPEndPoint(_ipAddress, _port)
                };

                var awaitable = new SocketAwaitable(args);

                try
                {
                    _packetNumber = 0;
                    await _socket.ConnectAsync(awaitable);
                }
                catch (SocketException e)
                {
                    Log.Debug(e);
                }
                catch (Exception e)
                {
                    Log.Error(e);
                    _state = TransportState.Disconnected;
                    throw;
                }

                switch (args.SocketError)
                {
                case SocketError.Success:
                case SocketError.IsConnected:
                    _state = TransportState.Connected;
                    break;

                default:
                    _state = TransportState.Disconnected;
                    break;
                }
                if (_state != TransportState.Connected)
                {
                    return;
                }
                _connectionCancellationTokenSource = new CancellationTokenSource();
                _receiverTask = StartReceiver(_connectionCancellationTokenSource.Token);
            }
        }
コード例 #32
0
        public Task SendAsync(byte[] payload, CancellationToken token)
        {
            ThrowIfDisposed();
            return(Task.Run(async() =>
            {
                var packet = new TcpTransportPacket(_packetNumber++, payload);

                var args = new SocketAsyncEventArgs();
                args.SetBuffer(packet.Data, 0, packet.Data.Length);

                var awaitable = new SocketAwaitable(args);
                await _socket.SendAsync(awaitable);
            }, token));
        }
コード例 #33
0
        public async Task WriteSync(IList <ArraySegment <byte> > buffers)
        {
            using (var args = new SocketAsyncEventArgs())
            {
                args.BufferList = buffers;
                var awaitable = new SocketAwaitable(args);
                await this.socket.SendAsync(awaitable);

                if (args.SocketError != SocketError.Success)
                {
                    this.isAlive = false;
                    ThrowHelper.ThrowSocketWriteError(this.endpoint, args.SocketError);
                }
            }
        }
コード例 #34
0
        private async Task StartSending(ClientStateObject state)
        {
            var byteData = Encoding.ASCII.GetBytes(state.OutboundMessage);
            var framedData = _framingProtocol.FrameMessage(byteData);
            var args = new SocketAsyncEventArgs();
            args.SetBuffer(framedData, 0, framedData.Length);
            var awaitable = new SocketAwaitable(args);
            await state.WorkSocket.SendAsync(awaitable);

            // complete sending to remote endpoint
            var bytesSent = args.BytesTransferred;
            _logger.Info(string.Format("Sent {0} bytes to server", bytesSent));
            await StartReceiving(state);

        }
コード例 #35
0
        private async Task StartAccepting()
        {
            _logger.Info("Started accepting connections...");

            var args = new SocketAsyncEventArgs();
            var awaitable = new SocketAwaitable(args);
            await _listener.AcceptAsync(awaitable);

            if (_isDisposed) return;

            _socket = args.AcceptSocket;
            _logger.Info("Connection accepted.");
            await StartReceiving(new StateObject { WorkSocket = _socket });

        }
コード例 #36
0
        public void TestSocketFlags()
        {
            // Default value.
            var awaitable = new SocketAwaitable();

            Assert.AreEqual(awaitable.SocketFlags, SocketFlags.None);

            // Assign value.
            awaitable.SocketFlags = SocketFlags.Broadcast;
            Assert.AreEqual(awaitable.SocketFlags, SocketFlags.Broadcast);

            // Clear awaitable.
            awaitable.Clear();
            Assert.AreEqual(awaitable.SocketFlags, SocketFlags.None);
        }
コード例 #37
0
ファイル: AwaitableSocket.cs プロジェクト: Nucs/nlib
 public static async Task ReadAsync(this Socket s)
 {
     // Reusable SocketAsyncEventArgs and awaitable wrapper 
     var args = new SocketAsyncEventArgs();
     args.SetBuffer(new byte[0x1000], 0, 0x1000);
     var awaitable = new SocketAwaitable(args);
     // Do processing, continually receiving from the socket 
     while (true)
     {
         await s.ReceiveAsync(awaitable);
         int bytesRead = args.BytesTransferred;
         if (bytesRead <= 0) break;
         Console.WriteLine(bytesRead);
     }
 }
コード例 #38
0
        private async Task <TransportMessage> ReceiveMessageInServer()
        {
            if (_serverSocket == null)
            {
                _serverSocket = _listener.EndAcceptSocket(_serverListenResult);
            }

            var buffer    = new byte[65535];
            var args      = new SocketAsyncEventArgs();
            var awaitable = new SocketAwaitable(args);
            var receiver  = new SocketReceiver(_serverSocket, args, awaitable, buffer);
            var protocol  = new SimpleProtocolDecoder(new JsonTransportSerializer());

            return(await protocol.Decode(receiver) as TransportMessage);
        }
コード例 #39
0
        public SocketByteHandler(Socket socket)
        {
            m_socket = socket;
#if VALUETASKSOURCE
            m_valueTaskSource = new ManualResetValueTaskSourceCore <int> {
                RunContinuationsAsynchronously = true
            };
            m_socketEventArgs            = new SocketAsyncEventArgs();
            m_socketEventArgs.Completed += (s, e) => PropagateSocketAsyncEventArgsStatus();
#else
            m_socketAwaitable = new SocketAwaitable(new SocketAsyncEventArgs());
#endif
            m_closeSocket    = socket.Dispose;
            RemainingTimeout = Constants.InfiniteTimeout;
        }
コード例 #40
0
ファイル: ListenerBinding.cs プロジェクト: lyrain2009/gsf
        /// <summary>
        /// Sends a response message.
        /// </summary>
        /// <param name="response">
        /// A <see cref="ISnmpMessage"/>.
        /// </param>
        /// <param name="receiver">Receiver.</param>
        public async Task SendResponseAsync(ISnmpMessage response, EndPoint receiver)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }

            if (response == null)
            {
                throw new ArgumentNullException(nameof(response));
            }

            if (receiver == null)
            {
                throw new ArgumentNullException(nameof(receiver));
            }

            if (_disposed)
            {
                throw new ObjectDisposedException("Listener");
            }

            if (_socket == null)
            {
                return;
            }

            byte[] buffer             = response.ToBytes();
            SocketAsyncEventArgs info = SocketExtension.EventArgsFactory.Create();

            try
            {
                info.RemoteEndPoint = receiver;
                info.SetBuffer(buffer, 0, buffer.Length);
                using (SocketAwaitable awaitable1 = new SocketAwaitable(info))
                {
                    await _socket.SendToAsync(awaitable1);
                }
            }
            catch (SocketException ex)
            {
                if (ex.SocketErrorCode != SocketError.Interrupted)
                {
                    // IMPORTANT: interrupted means the socket is closed.
                    throw;
                }
            }
        }
コード例 #41
0
 async Task ReadAsync(Socket s)
 {
     // Reusable SocketAsyncEventArgs and awaitable wrapper 
     var args = new SocketAsyncEventArgs();
     args.SetBuffer(new byte[0x100000], 0, 0x100000);
     var awaitable = new SocketAwaitable(args);
     while (true)
     {
         await s.ReceiveAsync(awaitable);
         int bytesRead = args.BytesTransferred;
         if (bytesRead <= 0) throw new Exception("Raw socket is disconnected");
         var ipPacket = new IPv4Packet(new ByteArraySegment(args.Buffer, 0, bytesRead));
         if (ipPacket.Version != IpVersion.IPv4 || ipPacket.Protocol!=IPProtocolType.TCP)
             continue;
         OnPacketReceived(ipPacket);
     }
 }
コード例 #42
0
        public void TestRemoteEndPoint()
        {
            // Default value.
            var awaitable = new SocketAwaitable();

            Assert.IsNull(awaitable.RemoteEndPoint);

            // Assign value.
            var endPoint = new IPEndPoint(IPAddress.Loopback, IPEndPoint.MaxPort);

            awaitable.RemoteEndPoint = endPoint;
            Assert.AreSame(awaitable.RemoteEndPoint, endPoint);

            // Clear awaitable.
            awaitable.Clear();
            Assert.IsNull(awaitable.RemoteEndPoint);
        }
コード例 #43
0
        public MessagingListenerClient(Socket socket, IMessageHandlerInvoker messageHandlerInvoker)
        {
            _socket = socket ?? throw new ArgumentNullException(nameof(socket));
            _messageHandlerInvoker = messageHandlerInvoker;

            // For inbound data
            _readAwaitable = new SocketAwaitable(_readArgs);
            _readArgs.SetBuffer(_readBuffer, 0, _readBuffer.Length);
            _receiver = new SocketReceiver(socket, _readArgs, _readAwaitable, _readBuffer);
            _decoder  = new SimpleProtocolDecoder(_serializer);

            // For outbound data
            _encoder        = new SimpleProtocolEncoder(_serializer);
            _writeArgs      = new SocketAsyncEventArgs();
            _writeAwaitable = new SocketAwaitable(_writeArgs);
            _sendState      = new SocketSender(_socket, _writeArgs, _writeAwaitable);
        }
コード例 #44
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="SocketAwaiter" /> class.
        /// </summary>
        /// <param name="awaitable">
        ///     The asynchronous socket arguments to await.
        /// </param>
        internal SocketAwaiter(SocketAwaitable awaitable)
        {
            this.awaitable = awaitable;
            this.awaitable.Arguments.Completed += delegate
            {
                var c = this.continuation ?? Interlocked.CompareExchange(ref this.continuation, sentinel, null);
                if (c != null)
                {
                    var syncContext = this.awaitable.ShouldCaptureContext ? this.SyncContext : null;
                    this.Complete();

                    if (syncContext != null)
                        syncContext.Post(s => c.Invoke(), null);
                    else
                        c.Invoke();
                }
            };
        }
コード例 #45
0
        public async void Start()
        {
            while (true)
            {
                try
                {
                    // Reusable SocketAsyncEventArgs and awaitable wrapper 
                    SocketAsyncEventArgs args = new SocketAsyncEventArgs();
                    args.SetBuffer(new byte[0x1000], 0, 0x1000);
                    args.RemoteEndPoint = _listener.LocalEndPoint;
                    SocketAwaitable awaitable = new SocketAwaitable(args);

                    // Do processing, continually receiving from the socket 
                    while (true)
                    {
                        await _listener.ReceiveFromAsync(awaitable);
                        int bytesRead = args.BytesTransferred;
                        if (bytesRead <= 0)
                        {
                            break;
                        }

                        if (OnRequest != null)
                        {
                            Task.Factory.StartNew(() => OnRequest(args));
                        }
                        else
                        {
                            // defaults to console dump if no listener is bound
                            Task.Factory.StartNew(() => ProcessReceiveFrom(args));
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
                // listener restarts if an exception occurs
            }
        }
コード例 #46
0
        private async Task StartReceiving(ClientStateObject state)
        {
            if (_isDisposed) return;
            if (!_socket.Connected) return;

            _logger.Info("Receiving message...");
            try
            {
                var args = new SocketAsyncEventArgs();
                args.SetBuffer(new byte[0x1000], 0, 0x1000);
                var awaitable = new SocketAwaitable(args);

                while (true)
                {
                    await _socket.ReceiveAsync(awaitable);
                    var bytesRead = args.BytesTransferred;
                    if (bytesRead <= 0) break;

                    _logger.Info(string.Format("Bytes Read: {0}", bytesRead));
                    if (awaitable.EventArgs.Buffer[0] == _framingProtocol.StartFrame || state.StartedReceiving)
                    {
                        state.Append(Encoding.ASCII.GetString(awaitable.EventArgs.Buffer, 0, bytesRead));
                    }

                    if (awaitable.EventArgs.Buffer[bytesRead - 1] == _framingProtocol.EndFrame) // We're done
                    {
                        InvokeMessageReceived(_framingProtocol.UnframeMessage(state.ToString()));
                    }
                }
            }
            catch (SocketException e)
            {
                if (e.SocketErrorCode != SocketError.ConnectionAborted) throw;
                // reconnect and send again
                _socket.Close();
                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                Send(state.OutboundMessage);
            }
        }
コード例 #47
0
 /// <summary>
 ///     Begins an awaitable request to disconnect from a remote endpoint.
 /// </summary>
 /// <param name="socket">
 ///     Socket that will connect to a remote host.
 /// </param>
 /// <param name="awaitable">
 ///     The <see cref="SocketAwaitable" /> object to use for this asynchronous socket operation.
 /// </param>
 /// <returns>
 ///     The specified <see cref="SocketAwaitable" /> which, when awaited, returns a
 ///     <see cref="SocketError" /> object that corresponds to the result of the connection attempt.
 /// </returns>
 /// <exception cref="ArgumentNullException">
 ///     <paramref name="socket" /> or <paramref name="awaitable" /> is null.
 /// </exception>
 /// <exception cref="InvalidOperationException">
 ///     A socket operation was already in progress using <paramref name="awaitable" />.
 /// </exception>
 /// <exception cref="NotSupportedException">
 ///     Windows XP or later is required for this method. This exception also occurs if the local endpoint
 ///     and the <see cref="SocketAwaitable.RemoteEndPoint" /> are not the same address family.
 ///     -or-
 ///     Address family of <see cref="Socket.LocalEndPoint" /> is different than the address family of
 ///     <see cref="SocketAsyncEventArgs.RemoteEndPoint" />.
 /// </exception>
 /// <exception cref="ObjectDisposedException">
 ///     <paramref name="socket" /> has been disposed.
 /// </exception>
 public static SocketAwaitable DisonnectAsync(this Socket socket, SocketAwaitable awaitable)
 {
     return OperateAsync(socket, awaitable, disconnectOp);
 }
コード例 #48
0
ファイル: AsyncSocket.cs プロジェクト: msjaelland/BOD-Server
 public SocketAwaitableEventWrapper()
 {
     EventArgs = new SocketAsyncEventArgs();
     SocketAwaitable = new SocketAwaitable(EventArgs);
 }
コード例 #49
0
        public void TestCopyingAfterDispose()
        {
            var pool = new SocketAwaitablePool(1);
            pool.Dispose();

            var array = new SocketAwaitable[1];
            (pool as ICollection).CopyTo(array, 0);
        }
コード例 #50
0
        private Task StartReceiver(CancellationToken token)
        {
            return Task.Run(async () =>
            {
                var args = new SocketAsyncEventArgs();
                args.SetBuffer(_readerBuffer, 0, _readerBuffer.Length);
                var awaitable = new SocketAwaitable(args);

                while (!token.IsCancellationRequested && _socket.IsConnected())
                {
                    try
                    {
                        if (_socket.Available == 0)
                        {
                            await Task.Delay(10, token);
                            continue;
                        }
                        await _socket.ReceiveAsync(awaitable);
                    }
                    catch (SocketException e)
                    {
                        Log.Debug(e);
                    }
                    if (args.SocketError != SocketError.Success)
                    {
                        break;
                    }
                    int bytesRead = args.BytesTransferred;
                    if (bytesRead <= 0)
                    {
                        break;
                    }

                    try
                    {
                        await ProcessReceivedDataAsync(new ArraySegment<byte>(_readerBuffer, 0, bytesRead));
                    }
                    catch (Exception e)
                    {
                        Log.Error(e, "Critical error while precessing received data.");
                        break;
                    }
                }
                try
                {
                    await DisconnectAsync();
                }
                catch (Exception e)
                {
                    Log.Debug(e);
                }
            }, token);
        }
コード例 #51
0
 public async void SendToAsync(SocketAsyncEventArgs args)
 {
     SocketAwaitable awaitable = new SocketAwaitable(args);
     await _listener.SendToAsync(awaitable);
 }
コード例 #52
0
        public async Task DisconnectAsync()
        {
            ThrowIfDisposed();
            using (await _stateAsyncLock.LockAsync())
            {
                if (_state == ClientTransportState.Disconnected)
                {
                    return;
                }
                var args = new SocketAsyncEventArgs();
                var awaitable = new SocketAwaitable(args);
                try
                {
                    if (_socket.Connected)
                    {
                        _socket.Shutdown(SocketShutdown.Both);
                        await _socket.DisconnectAsync(awaitable);
                    }
                }
                catch (SocketException e)
                {
                    Log.Debug(e);
                }

                _state = ClientTransportState.Disconnected;
            }
        }
コード例 #53
0
        public Task SendAsync(byte[] payload, CancellationToken token)
        {
            ThrowIfDisposed();
            return Task.Run(async () =>
            {
                var packet = new TcpTransportPacket(_packetNumber++, payload);

                var args = new SocketAsyncEventArgs();
                args.SetBuffer(packet.Data, 0, packet.Data.Length);

                var awaitable = new SocketAwaitable(args);
                await _socket.SendAsync(awaitable);
            }, token);
        }
コード例 #54
0
        /// <summary>
        /// The actuall async function responsible for sending Payloads with UDP to a Carbon Backend.
        /// </summary>
        /// <param name="payloads"></param>
        /// <returns></returns>
        protected override async Task SendAsync(List<byte[]> payloads)
        {
            if (pSocket == null)
            {
                pSocket = new Socket(Endpoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
                //pSocket.SendToAsync()
                pSocket.Connect(Endpoint); //UDP doesnt connect. Only sets remote end point.
            }

#if !NOFANCYASYNC

            var args = new SocketAsyncEventArgs();
            //args.RemoteEndPoint = Endpoint;
            var awaitable = new SocketAwaitable(args);

            // udp with connect??
            //await pSocket.ConnectAsync(awaitable);

            foreach(var msg in payloads)
            {
                args.SetBuffer(msg, 0, msg.Length);

                await pSocket.SendAsync(awaitable);
            }

#else

            foreach(var msg in payloads)
            {
                var result = pSocket.BeginSend(msg, 0, msg.Length, SocketFlags.None, null, pSocket);
                await Task.Factory.FromAsync(result, pSocket.EndSend);
            }

#endif
        }
コード例 #55
0
        public async Task ConnectAsync(CancellationToken token)
        {
            ThrowIfDisposed();
            ThrowIfOnServerSide();
            using (await _stateAsyncLock.LockAsync(token))
            {
                if (State == ClientTransportState.Connected)
                {
                    return;
                }

                var args = new SocketAsyncEventArgs {RemoteEndPoint = _remoteEndPoint};
                
                var awaitable = new SocketAwaitable(args);

                try
                {
                    _packetNumber = 0;
                    await _socket.ConnectAsync(awaitable);
                }
                catch (SocketException e)
                {
                    Log.Debug(e);
                }
                catch (Exception e)
                {
                    Log.Error(e);
                    _state = ClientTransportState.Disconnected;
                    throw;
                }

                switch (args.SocketError)
                {
                    case SocketError.Success:
                    case SocketError.IsConnected:
                        _state = ClientTransportState.Connected;
                        break;
                    default:
                        _state = ClientTransportState.Disconnected;
                        break;
                }
                if (_state != ClientTransportState.Connected)
                {
                    return;
                }
                _connectionCancellationTokenSource = new CancellationTokenSource();
                _receiverTask = StartReceiver(_connectionCancellationTokenSource.Token);
            }
        }
コード例 #56
0
 /// <summary>
 ///     Begins an awaitable request to receive data from a connected <see cref="Socket" /> object.
 /// </summary>
 /// <param name="socket">
 ///     Socket that will receive data.
 /// </param>
 /// <param name="awaitable">
 ///     The <see cref="SocketAwaitable" /> object to use for this asynchronous socket operation.
 /// </param>
 /// <returns>
 ///     The specified <see cref="SocketAwaitable" /> which, when awaited, will hold the received
 ///     data in its <see cref="SocketAsyncEventArgs.Buffer" /> property. Awaiter of <see cref="SocketAwaitable" />
 ///     returns a <see cref="SocketError" /> object that corresponds to the result of the asynchronous operation.
 /// </returns>
 /// <exception cref="ArgumentNullException">
 ///     <paramref name="socket" /> or <paramref name="awaitable" /> is null.
 /// </exception>
 /// <exception cref="InvalidOperationException">
 ///     A socket operation was already in progress using <paramref name="awaitable"/>.
 /// </exception>
 /// <exception cref="NotSupportedException">
 ///     Windows XP or later is required for this method.
 /// </exception>
 /// <exception cref="ObjectDisposedException">
 ///     <paramref name="socket" /> has been disposed.
 /// </exception>
 public static SocketAwaitable ReceiveAsync(this Socket socket, SocketAwaitable awaitable)
 {
     return OperateAsync(socket, awaitable, receiveOp);
 }
コード例 #57
0
 /// <summary>
 ///     Sends data asynchronously to a connected <see cref="Socket" /> object and returns a
 ///     <see cref="SocketAwaitable" /> to await.
 /// </summary>
 /// <param name="socket">
 ///     Socket to send the data to.
 /// </param>
 /// <param name="awaitable">
 ///     The <see cref="SocketAwaitable" /> object to use for this asynchronous socket operation.
 /// </param>
 /// <returns>
 ///     The specified <see cref="SocketAwaitable" /> which, when awaited, will return a
 ///     <see cref="SocketError" /> object that corresponds to the result of the send operation.
 /// </returns>
 /// <exception cref="ArgumentNullException">
 ///     <paramref name="socket" /> or <paramref name="awaitable" /> is null.
 /// </exception>
 /// <exception cref="InvalidOperationException">
 ///     A socket operation was already in progress using <paramref name="awaitable"/>.
 /// </exception>
 /// <exception cref="NotSupportedException">
 ///     Windows XP or later is required for this method.
 /// </exception>
 /// <exception cref="ObjectDisposedException">
 ///     <paramref name="socket" /> has been disposed.
 /// </exception>
 public static SocketAwaitable SendAsync(this Socket socket, SocketAwaitable awaitable)
 {
     return OperateAsync(socket, awaitable, sendOp);
 }
コード例 #58
0
        /// <summary>
        ///     Calls the specified asynchronous method of a <see cref="Socket" /> and returns an awaitable
        ///     object that provides the operation result when awaited.
        /// </summary>
        /// <param name="socket">
        ///     <see cref="Socket" /> to run an asynchronous operation.
        /// </param>
        /// <param name="awaitable">
        ///     The <see cref="SocketAwaitable" /> object to use for this asynchronous socket operation.
        /// </param>
        /// <param name="operation">
        ///     Socket operation to perform.
        /// </param>
        /// <returns>
        ///     A <see cref="SocketAwaitable" /> which, when awaited, returns a <see cref="SocketError" />
        ///     object that corresponds to the result of <paramref name="operation" />.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="socket" /> or <paramref name="awaitable" /> is null.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        ///     A socket operation was already in progress using <paramref name="awaitable"/>.
        ///     -or-
        ///     For accept operations:
        ///     <paramref name="socket" /> is not bound, is not listening for connections, or is already connected.
        ///     -or-
        ///     For connect operations:
        ///     <paramref name="socket" /> is listening.
        /// </exception>
        /// <exception cref="NotSupportedException">
        ///     Windows XP or later is required for this method.
        ///     -or-
        ///     For connect operations:
        ///     Address family of <see cref="Socket.LocalEndPoint" /> is different than the address family of
        ///     <see cref="SocketAsyncEventArgs.RemoteEndPoint" />.
        /// </exception>
        /// <exception cref="ObjectDisposedException">
        ///     <paramref name="socket" /> has been disposed.
        /// </exception>
        /// <exception cref="SecurityException">
        ///     For connection operations:
        ///     A caller higher in the call stack does not have permission for the requested operation.
        /// </exception>
        private static SocketAwaitable OperateAsync(
            Socket socket,
            SocketAwaitable awaitable,
            Func<Socket, SocketAwaitable, bool> operation)
        {
            if (socket == null)
                throw new ArgumentNullException("socket", "Socket must not be null.");

            if (awaitable == null)
                throw new ArgumentNullException("awaitable", "Awaitable must not be null.");

            var a = awaitable.GetAwaiter();
            lock (a.SyncRoot)
            {
                if (!a.IsCompleted)
                    throw new InvalidOperationException(
                        "A socket operation is already in progress using the same awaitable arguments.");

                a.Reset();
                if (awaitable.ShouldCaptureContext)
                    a.SyncContext = SynchronizationContext.Current;
            }
            
            try
            {
                if (!operation.Invoke(socket, awaitable))
                    a.Complete();
            }
            catch (SocketException x)
            {
                a.Complete();
                awaitable.Arguments.SocketError = x.SocketErrorCode != SocketError.Success
                    ? x.SocketErrorCode
                    : SocketError.SocketError;
            }
            catch (Exception)
            {
                a.Complete();
                awaitable.Arguments.SocketError = SocketError.Success;
                throw;
            }

            return awaitable;
        }
コード例 #59
0
        public async Task SendFramedData(string message)
        {
            var msg = Encoding.UTF8.GetBytes(message);
            var framedMsg = _framingProtocol.FrameMessage(msg);
            if (_socket != null)
            {
                var args = new SocketAsyncEventArgs() { };
                args.SetBuffer(framedMsg, 0, framedMsg.Length);
                var awaitable = new SocketAwaitable(args);
                await _socket.SendAsync(awaitable);

                _logger.Info("Framed message sent.");
                _socket.Shutdown(SocketShutdown.Both);
                _logger.Info("Disconnecting from system...");

                await _socket.DisconnectAsync(awaitable);
                _logger.Info("System disconnected.");
                await StartAccepting();

            }
        }
コード例 #60
0
 /// <summary>
 ///     Begins an awaitable operation to accept an incoming connection attempt.
 /// </summary>
 /// <param name="socket">
 ///     Socket that will accept the connection.
 /// </param>
 /// <param name="awaitable">
 ///     The <see cref="SocketAwaitable" /> object to use for this asynchronous socket operation.
 /// </param>
 /// <returns>
 ///     <paramref name="awaitable" />, when awaited, will have the accepted socket
 ///     in its <see cref="SocketAwaitable.AcceptSocket" /> property. Awaiter of the result returns a
 ///     <see cref="SocketError" /> that corresponds to the result of this asynchronous operation.
 /// </returns>
 /// <exception cref="ArgumentNullException">
 ///     <paramref name="socket" /> or <paramref name="awaitable" /> is null.
 /// </exception>
 /// <exception cref="ArgumentException">
 ///     <see cref="SocketAwaitable.Buffer" /> of the <paramref name="awaitable" /> is not large enough.
 ///     The buffer must be at least 2 * (sizeof(SOCKADDR_STORAGE + 16) bytes.
 /// </exception>
 /// <exception cref="InvalidOperationException">
 ///     <paramref name="socket" /> is not bound, is not listening for connections, or is already connected.
 ///     -or-
 ///     A socket operation was already in progress using <paramref name="awaitable" />
 /// </exception>
 /// <exception cref="NotSupportedException">
 ///     Windows XP or later is required for this method.
 /// </exception>
 /// <exception cref="ObjectDisposedException">
 ///     <paramref name="socket" /> has been disposed.
 /// </exception>
 public static SocketAwaitable AcceptAsync(this Socket socket, SocketAwaitable awaitable)
 {
     return OperateAsync(socket, awaitable, acceptOp);
 }