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); }
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()); } } }
public static SocketAwaitable SendAsync(this Socket socket, SocketAwaitable awaitable) { awaitable.Reset(); if (!socket.SendAsync(awaitable.EventArgs)) awaitable.WasCompleted = true; return awaitable; }
public static SocketAwaitable ReceiveAsync(this Socket socket, SocketAwaitable awaitable) { awaitable.Reset(); if (!socket.ReceiveAsync(awaitable.m_eventArgs)) awaitable.m_wasCompleted = true; return awaitable; }
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); }
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)); }
/// <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); }
/// <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); }
public static SocketAwaitable SendToAsync(this Socket socket, SocketAwaitable awaitable) { awaitable.Reset(); if (!socket.SendToAsync(awaitable.m_eventArgs)) { awaitable.m_wasCompleted = true; } return awaitable; }
public void TestDisposing() { var awaitable = new SocketAwaitable(); Assert.IsFalse(awaitable.IsDisposed); awaitable.Dispose(); Assert.IsTrue(awaitable.IsDisposed); }
public SocketByteHandler(Socket socket) { m_socket = socket; var socketEventArgs = new SocketAsyncEventArgs(); m_socketAwaitable = new SocketAwaitable(socketEventArgs); m_closeSocket = socket.Dispose; RemainingTimeout = Constants.InfiniteTimeout; }
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); }
/// <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; }
/// <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; }
/// <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; }
public Listener( ListenerSettings settings, Func<Socket, IWorker> createWorker) { _settings = settings; _createWorker = createWorker; // create awaitable _awaitable = new SocketAwaitable(Timeout.InfiniteTimeSpan); }
private static SocketAwaitable ReceiveAsync(this Socket socket, SocketAwaitable awaitable) { awaitable.Reset(); if (!socket.ReceiveAsync(awaitable.EventArgs)) { awaitable.IsCompleted = true; } return(awaitable); }
/// <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; }
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); } }
public static SocketAwaitable ReceiveAsync(this Socket socket, SocketAwaitable awaitable) { awaitable.Reset(); if (!socket.ReceiveAsync(awaitable.m_eventArgs)) { awaitable.m_wasCompleted = true; } return(awaitable); }
public void TestCopyingAfterDispose() { var pool = new SocketAwaitablePool(1); pool.Dispose(); var array = new SocketAwaitable[1]; (pool as ICollection).CopyTo(array, 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); }
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)); }
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); }
public static async Task SendAsync(this Socket socket, SocketAwaitable awaitable) { var isPending = socket.SendAsync(awaitable._eventArgs); if (!isPending) { return; } awaitable.Reset(); await awaitable; }
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)); }
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); } }
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); } }
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); }
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; } }
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); } }
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)); }
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); } } }
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); }
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 }); }
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); }
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); } }
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); }
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; }
/// <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; } } }
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); } }
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); }
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); }
/// <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(); } }; }
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 } }
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); } }
/// <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); }
public SocketAwaitableEventWrapper() { EventArgs = new SocketAsyncEventArgs(); SocketAwaitable = new SocketAwaitable(EventArgs); }
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); }
public async void SendToAsync(SocketAsyncEventArgs args) { SocketAwaitable awaitable = new SocketAwaitable(args); await _listener.SendToAsync(awaitable); }
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; } }
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); }
/// <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 }
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); } }
/// <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); }
/// <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); }
/// <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; }
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(); } }
/// <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); }