...basically exactly what the title says. NetworkStream.Length is not implemented. What's an alternative?
I'm trying to make a recursive series of async callbacks that encase calls to NetworkStream.BeginRead(...). To know when I've hit my base case and received all bytes I need to know the length of bytes in the stream. Is there a workaround for this?
Code (the entry point to this code is write after TcpListern.BeginAcceptTcpClient call.:
private void StartRead(IAsyncResult ar)
{
try
{
//Do an initial read:
AsyncClient client = (AsyncClient)ar.AsyncState;
int amountRead = 0;
try
{
amountRead = client.ClientStream.EndRead(ar);
}
catch (IOException io)
{
ProcessDebugLog("Async read complete", io);
client.ClientStream.Close();
return;
}
string text = Encoding.UTF8.GetString(client.Bytes, 0, amountRead);
//If TCP segmentation has occurred, more blocks will have
// to get read in:
if (client.ClientStream.Position < client.ClientStream.Length /*EXCEPTION HERE*/)
{
try
{
client.ClientStream.BeginRead(client.Bytes, 0, client.Bytes.Length, StartRead, client);
}
catch (IOException io)
{
ProcessDebugLog("Async read complete", io);
client.ClientStream.Close();
}
}
else
{
client.ClientStream.Close();
}
}
catch (Exception ex)
{
ProcessDebugLog("ERROR - StartRead", ex);
}
}
...basically exactly what the title says. NetworkStream.Length is not implemented. What's an alternative?
You keep reading until the end of the stream. There is no alternative to this - until the stream has been closed, there can always be more data.
If you control the protocol, then if a stream can contain several "messages" you should length-prefix each message. (You can use a delimiter as an alternative, but that's messier.)
Note that you should not decode from binary to text until you've got all the data, or you should use a Decoder
which is able to maintain state of "uncompleted" characters - in case your read ends up splitting half way through a character.