private void ReadCallback(UvStream stream, int nread, Exception error, object stateObject) { UvTcp client = null; try { if (error != null) { throw error; } // When receiving a TCP handle over an IPC pipe the accept logic is slightly different: // First we receive some data over the pipe (usually some dummy message) // and then we check if we got some handle as well by ckecking the UvPipe.PendingCount. // If we do, we can simply accept the pending handle as usual. var pipe = (UvPipe)stream; if (pipe.PendingCount() > 0) { client = new UvTcp(this.Worker.Loop); pipe.Accept(client); this.OnNewConnectionAccepted(client); } } catch (Exception exception) { lock (this.SyncRoot) { this.CloseBaseSocket(); } client?.Close(); if (exception is UvErrorException errorException && errorException.ErrorCode == UvErrorCode.EOF) { // Ignore EOF errors }
private ArraySegment <byte> AllocCallback(UvStream stream, int suggestedSize, object stateObject) { return(new ArraySegment <byte>(this.pipeAcceptBuffer)); }
public static extern int uv_write2(UvWriteRequest req, UvStream handle, UvBuffer[] bufs, int nbufs, UvStream sendHandle, UvWriteCallback cb);
public static extern int uv_accept(UvNetworkStream server, UvStream client);
public static extern int uv_read_stop(UvStream handle);
public static extern int uv_read_start(UvStream handle, UvAllocCallback allocCallback, UvReadCallback readCallback);
public static extern int uv_shutdown(UvShutdownRequest req, UvStream handle, UvShutdownCallback cb);
private void ReadCallback(UvStream stream, int receivedBytes, Exception error, object stateObject) { try { if (error != null) { throw error; } var state = (ReceiveState)stateObject; state.ReceivedBytes += receivedBytes; int remainingBytes; int nextPacketOffset = 0; do { remainingBytes = this.Protocol.TryRead( state.Buffer.Buffer, state.Buffer.Offset + nextPacketOffset, state.ReceivedBytes - nextPacketOffset, out var packet); if (packet != null) { // Synchronously handle packet before reading the next packet this.HandlePacket(packet); } if (remainingBytes == 0) { // Packet has been received completely, no other data currently available state.ReceivedBytes = 0; // Return to a buffer of recommended size if (state.Buffer.Length > this.Protocol.RecommendedBufferSize) { BufferSegment bufferToReturn = null; try { var oldBuffer = state.Buffer; state.Buffer = this.BufferPool.Acquire(this.Protocol.RecommendedBufferSize); bufferToReturn = oldBuffer; } finally { bufferToReturn?.Dispose(); } } } else if (remainingBytes < 0) { // There is complete another packet in our buffer, calculate it's offset nextPacketOffset = state.ReceivedBytes + remainingBytes; } else if (state.ReceivedBytes + remainingBytes > state.Buffer.Length) { // There's next packet's incomplete body left and it does not fit into the rest of the buffer. // We need to move it at the beginning of the buffer. var nextPacketSize = state.ReceivedBytes - nextPacketOffset + remainingBytes; var sourceBuffer = state.Buffer; BufferSegment bufferToReturn = null; try { if (nextPacketSize > state.Buffer.Length) { // The packet is bigger than our current buffer. We should try to acquire a bigger one from the buffer pool. state.Buffer = this.BufferPool.Acquire(nextPacketSize); bufferToReturn = sourceBuffer; } // Basically cutting the used part of received butes and storing the rest into the state's buffer state.ReceivedBytes -= nextPacketOffset; Buffer.BlockCopy( sourceBuffer.Buffer, sourceBuffer.Offset + nextPacketOffset, state.Buffer.Buffer, state.Buffer.Offset, state.ReceivedBytes); } finally { bufferToReturn?.Dispose(); } } }while (remainingBytes < 0); // Wait for another read callback } catch (UvErrorException exception) { if (exception.ErrorCode == UvErrorCode.EOF || exception.ErrorCode == UvErrorCode.ECONNRESET) { this.Close(); } else { this.Close(exception); } } catch (Exception exception) { this.Close(exception); } }
private ArraySegment <byte> AllocCallback(UvStream stream, int suggestedSize, object stateObject) { var state = (ReceiveState)stateObject; return(new ArraySegment <byte>(state.Buffer.Buffer, state.Buffer.Offset + state.ReceivedBytes, state.Buffer.Length - state.ReceivedBytes)); }