janet blackquill
janet blackquill
CC#
Created by janet blackquill on 7/24/2023 in #help
✅ [done] system.io.pipelines: unable to get last byte of what client has sent
i have a tcp server using the System.Net stuff, and it's just using the stream wrapper methods: PipeReader.Create(ClientStream) to obtain a PipeReader i am having difficulty of getting the last byte of what a client has sent when i'm slicing stuff notably, i can read the whole buffer in one fell swoop, but if i do this slice-and-advane dance, i'm unable to get at the last byte code:
var result = await reader.ReadAtLeastAsync(2);
var buffer = result.Buffer;
var position = buffer.GetPosition(sizeof(UInt16));
var packetLengthBuffer = buffer.Slice(0, position);
reader.AdvanceTo(packetLengthBuffer.End);
if (result.IsCompleted)
return null;

var packetLength = ReadUInt16(packetLengthBuffer);
if (packetLength < 3)
return null;

Console.WriteLine($"{dbg} length {packetLength} contents: {Convert.ToHexString(packetLengthBuffer.First.Span)}");

result = await reader.ReadAtLeastAsync(1);
buffer = result.Buffer;
position = buffer.GetPosition(sizeof(byte));
var packetTypeBuffer = buffer.Slice(0, position);
reader.AdvanceTo(packetTypeBuffer.End);
if (result.IsCompleted)
return null;

var packetType = ReadUInt8(packetTypeBuffer);

Console.WriteLine($"{dbg} type {packetType} contents: {Convert.ToHexString(packetTypeBuffer.First.Span)}");

var bodyLength = packetLength - 3;

result = await reader.ReadAtLeastAsync(bodyLength);
buffer = result.Buffer;
position = buffer.GetPosition(bodyLength);
var packetDataBuffer = buffer;
reader.AdvanceTo(packetDataBuffer.End);
if (result.IsCompleted)
return null;

Console.WriteLine($"{dbg} body contents: {Encoding.UTF8.GetString(packetDataBuffer.First.Span)}");
// throws exception here ^^^
// doesn't throw if i read bodyLength - 1 bytes, but i need that last byte

return new(packetType, packetDataBuffer);
var result = await reader.ReadAtLeastAsync(2);
var buffer = result.Buffer;
var position = buffer.GetPosition(sizeof(UInt16));
var packetLengthBuffer = buffer.Slice(0, position);
reader.AdvanceTo(packetLengthBuffer.End);
if (result.IsCompleted)
return null;

var packetLength = ReadUInt16(packetLengthBuffer);
if (packetLength < 3)
return null;

Console.WriteLine($"{dbg} length {packetLength} contents: {Convert.ToHexString(packetLengthBuffer.First.Span)}");

result = await reader.ReadAtLeastAsync(1);
buffer = result.Buffer;
position = buffer.GetPosition(sizeof(byte));
var packetTypeBuffer = buffer.Slice(0, position);
reader.AdvanceTo(packetTypeBuffer.End);
if (result.IsCompleted)
return null;

var packetType = ReadUInt8(packetTypeBuffer);

Console.WriteLine($"{dbg} type {packetType} contents: {Convert.ToHexString(packetTypeBuffer.First.Span)}");

var bodyLength = packetLength - 3;

result = await reader.ReadAtLeastAsync(bodyLength);
buffer = result.Buffer;
position = buffer.GetPosition(bodyLength);
var packetDataBuffer = buffer;
reader.AdvanceTo(packetDataBuffer.End);
if (result.IsCompleted)
return null;

Console.WriteLine($"{dbg} body contents: {Encoding.UTF8.GetString(packetDataBuffer.First.Span)}");
// throws exception here ^^^
// doesn't throw if i read bodyLength - 1 bytes, but i need that last byte

return new(packetType, packetDataBuffer);
6 replies