/// <summary> /// Recieves an asynchronous recieve operation and loops until the response body has been read. /// </summary> /// <param name="socket">The <see cref="Socket"/> which the asynchronous operation is associated with.</param> /// <param name="e">The <see cref="SocketAsyncEventArgs"/> that is being used for the operation.</param> public void Receive(Socket socket, SocketAsyncEventArgs e) { while (true) { var state = (SocketAsyncState)e.UserToken; Log.Debug("Receive {0} bytes for opaque{1} with {2} on server {3} offset{4}", e.BytesTransferred, state.Opaque, Identity, EndPoint, state.SendOffset); if (e.SocketError == SocketError.Success) { //socket was closed on recieving side if (e.BytesTransferred == 0) { Log.Debug("Connection {0} has failed in receive with {1} bytes.", Identity, e.BytesTransferred); IsDead = true; if (state.Completed == null) { if (!Disposed) { _requestCompleted.Set(); } } else { ConnectionPool.Release(this); state.Exception = new SocketException(10054); state.Completed(state); } break; } state.BytesReceived += e.BytesTransferred; state.Data.Write(e.Buffer, state.SendOffset, e.BytesTransferred); //if first loop get the length of the body from the header if (state.BodyLength == 0) { state.BodyLength = Converter.ToInt32(state.Data.ToArray(), HeaderIndexFor.Body); } if (state.BytesReceived < state.BodyLength + 24) { var bufferSize = state.BodyLength < Configuration.BufferSize ? state.BodyLength : Configuration.BufferSize; e.SetBuffer(state.SendOffset, bufferSize); var willRaiseCompletedEvent = socket.ReceiveAsync(e); if (!willRaiseCompletedEvent) { continue; } } else { //if the callback is null we are in blocking mode if (state.Completed == null) { Log.Debug("Complete with set {0} with {1} on server {2}", state.Opaque, Identity, EndPoint); _requestCompleted.Set(); } else { Log.Debug("Complete {0} with {1} on server {2}", state.Opaque, Identity, EndPoint); ConnectionPool.Release(this); state.Completed(state); } } } else { IsDead = true; state.Exception = new SocketException((int)e.SocketError); Log.Debug("Error: {0} - {1}", Identity, state.Exception); //if the callback is null we are in blocking mode if (state.Completed == null) { if (!Disposed) { _requestCompleted.Set(); } } else { ConnectionPool.Release(this); state.Completed(state); } } break; } UpdateLastActivity(); }
public override async void SendAsync(byte[] request, Func <SocketAsyncState, Task> callback, ISpan span, ErrorMap errorMap) { ExceptionDispatchInfo capturedException = null; SocketAsyncState state = null; try { var opaque = Converter.ToUInt32(request, HeaderIndexFor.Opaque); state = new SocketAsyncState { Data = MemoryStreamFactory.GetMemoryStream(), Opaque = opaque, Buffer = request, Completed = callback, DispatchSpan = span, CorrelationId = CreateCorrelationId(opaque), ErrorMap = errorMap }; await _sslStream.WriteAsync(request, 0, request.Length).ContinueOnAnyContext(); state.SetIOBuffer(BufferAllocator.GetBuffer()); state.BytesReceived = await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, state.BufferLength).ContinueOnAnyContext(); //write the received buffer to the state obj await state.Data.WriteAsync(state.Buffer, state.BufferOffset, state.BytesReceived).ContinueOnAnyContext(); state.BodyLength = Converter.ToInt32(state.Buffer, state.BufferOffset + HeaderIndexFor.BodyLength); while (state.BytesReceived < state.BodyLength + 24) { var bufferLength = state.BufferLength - state.BytesSent < state.BufferLength ? state.BufferLength - state.BytesSent : state.BufferLength; state.BytesReceived += await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, bufferLength).ContinueOnAnyContext(); await state.Data.WriteAsync(state.Buffer, state.BufferOffset, state.BytesReceived - (int)state.Data.Length).ContinueOnAnyContext(); } await callback(state).ContinueOnAnyContext(); } catch (Exception e) { IsDead = true; capturedException = ExceptionDispatchInfo.Capture(e); } finally { ConnectionPool.Release(this); if (state.IOBuffer != null) { BufferAllocator.ReleaseBuffer(state.IOBuffer); } } if (capturedException != null) { var sourceException = capturedException.SourceException; if (state == null) { await callback(new SocketAsyncState { Exception = capturedException.SourceException, Status = (sourceException is SocketException) ? ResponseStatus.TransportFailure : ResponseStatus.ClientFailure }).ContinueOnAnyContext(); } else { state.Exception = sourceException; await state.Completed(state).ContinueOnAnyContext(); Log.Debug(sourceException); } } }
public override async void SendAsync(byte[] request, Func <SocketAsyncState, Task> callback) { SocketAsyncState state = null; byte[] buffer = null; try { state = new SocketAsyncState { Data = new MemoryStream(), Opaque = Converter.ToUInt32(request, HeaderIndexFor.Opaque), Buffer = request, Completed = callback }; await _sslStream.WriteAsync(request, 0, request.Length); state.Buffer = BufferManager.TakeBuffer(Configuration.BufferSize); state.BytesReceived = await _sslStream.ReadAsync(state.Buffer, 0, Configuration.BufferSize); //write the received buffer to the state obj await state.Data.WriteAsync(state.Buffer, 0, state.BytesReceived); state.BodyLength = Converter.ToInt32(state.Buffer, HeaderIndexFor.BodyLength); while (state.BytesReceived < state.BodyLength + 24) { var bufferLength = state.Buffer.Length - state.BytesSent < Configuration.BufferSize ? state.Buffer.Length - state.BytesSent : Configuration.BufferSize; state.BytesReceived += await _sslStream.ReadAsync(state.Buffer, 0, bufferLength); await state.Data.WriteAsync(state.Buffer, 0, state.BytesReceived - (int)state.Data.Length); } await callback(state); } catch (Exception e) { IsDead = true; if (state == null) { callback(new SocketAsyncState { Exception = e, Status = (e is SocketException) ? ResponseStatus.TransportFailure : ResponseStatus.ClientFailure }); } else { state.Exception = e; state.Completed(state); Log.Debug(e); } } finally { ConnectionPool.Release(this); if (buffer != null) { BufferManager.ReturnBuffer(buffer); } } }
internal SslConnection(ConnectionPool <SslConnection> connectionPool, Socket socket, IByteConverter converter) : this(connectionPool, socket, new SslStream(new NetworkStream(socket)), converter) { }
internal SslConnection(ConnectionPool <SslConnection> connectionPool, Socket socket, IByteConverter converter) : this(connectionPool, socket, new SslStream(new NetworkStream(socket), true, ServerCertificateValidationCallback), converter) { }
/// <summary> /// Recieves an asynchronous recieve operation and loops until the response body has been read. /// </summary> /// <param name="socket">The <see cref="Socket"/> which the asynchronous operation is associated with.</param> /// <param name="e">The <see cref="SocketAsyncEventArgs"/> that is being used for the operation.</param> public void Receive(Socket socket, SocketAsyncEventArgs e) { while (true) { var state = (SocketAsyncState)e.UserToken; if (e.SocketError == SocketError.Success) { //socket was closed on recieving side if (e.BytesTransferred == 0) { _requestCompleted.Set(); return; } state.BytesReceived += e.BytesTransferred; state.Data.Write(e.Buffer, 0, e.BytesTransferred); //if first loop get the length of the body from the header if (state.BodyLength == 0) { state.BodyLength = Converter.ToInt32(state.Data.GetBuffer(), HeaderIndexFor.Body); } if (state.BytesReceived < state.BodyLength + 24) { var bufferSize = state.BodyLength < Configuration.BufferSize ? state.BodyLength : Configuration.BufferSize; e.SetBuffer(0, bufferSize); var willRaiseCompletedEvent = socket.ReceiveAsync(e); if (!willRaiseCompletedEvent) { continue; } } else { //if the callback is null we are in blocking mode if (state.Completed == null) { _requestCompleted.Set(); } else { ConnectionPool.Release(this); state.Completed(state); } } } else { IsDead = true; state.Exception = new SocketException((int)e.SocketError); //if the callback is null we are in blocking mode if (state.Completed == null) { _requestCompleted.Set(); } else { ConnectionPool.Release(this); state.Completed(state); } } break; } }