Home > Mobile >  C# - How to know how many bytes are left in TcpClient after perform SslStream.Read
C# - How to know how many bytes are left in TcpClient after perform SslStream.Read

Time:12-08

I'm doing a client-server app, the server will check when there is data available (TcpClient.Available > 0) to read, but when it runs SslStream.Read, even though I know how many bytes I need to read, it still sets the TcpClient.Available back to 0 and leave the already read bytes ... unread by my code because the condition (TcpClient.Available > 0) would be false so that the server won't do anything with the additional bytes until the client sends more bytes, which is not wanted, the server should process all the bytes sent by the client as soon as possible. Here is some code:

static void main()
{
    TcpClient tcpClient = listener.AcceptTcpClient();
    SslStream s = new SslStream(tcpClient.GetStream(), false);
    //authenticate etc ...
    while (true)
    {
        if (tcpClient.Available > 0) // now this condition is false until
                                     // the client send more bytes
                                     // which is not wanted
            work(tcpClient);
    }
}
    
static void work(TcpClient c)
{
    //client sent 50 bytes
    byte[] data = new byte[10];
    s.Read(data, 0, 10); // I know this is not guaranteed to read 10 bytes 
    //so I have a while loop to read until it receives all the byes, this line is just for example
    
    // do something with the 10 bytes I read, back to the while loop
 }
  

my "work" actually create a new thread to do the work and lock that client until the work is done so that that client will not call work until the work is done

Since I know how many bytes are needed for a "work" to run I only read that number of bytes and unlock the client so that the client can "work" again

And of course there are other clients that need to work too, here I just show one to demonstrate the problem

PS: Thank you all for all the answers and comments, I've looked into them, will definitely change how I write code in the future but right now I've found the quick solution myself

And my program works as expected, even faster (I don't really know how) than when it had that unwanted behavior and I don't have to rework my entire server for it to work.

I've posted my answer below, since I use it and it works, I'll mark it as answered.

CodePudding user response:

You generally don't know how many bytes is left to read from stream.

But you can just read from the stream "while it's reading" because SslStream.Read returns the amount of bytes read!

So your code transforms into simple

while (s.Read(data, 0, 10) > 0)
{
    // do something with the bytes you've read
}

It's the way people work with streams in general - reading them by chunks while it's reading.

You can see it (And much more! You should definetely check it out) in the examples from the documentation I've linked earlier

CodePudding user response:

I changed

if (tcpClient.Available > 0) 

to

if (tcpClient.Available > 0 || s.CanRead)

and it works as expected

  • Related