4

When I read an a .Net SSLStream, I can't seem to read it all in one go. The read method always gets the first byte only. I need to loop to get the remaining data no matter the data or buffer size.

Example :

Client

var message = new byte[]{1,2,3,4,5};
   sslStream.Write(messsage);
   sslStream.Flush();

Server

byte[] buffer = new byte[4000];
bytes = sslStream.Read(buffer, 0, buffer.Length);

Am I doing something wrong ? Why is it reading only one byte on the first read ?

J-F
  • 41
  • 1
  • 4

3 Answers3

3

Streaming APIs do not promise you to return a specific number of bytes per read. You can read any number of bytes starting from 1. YOur code must be able to deal with receiving the data byte-wise even if you asked for bigger chunks and even if you sent bigger chunks.

The best fix for this is to not use sockets. Use a higher level API such as WCF, SignalR, HTTP, ...

If you insist you probably should use BinaryReader/Writer to send your data. That makes it quite easy.

If you don't want any of that you need to read in a loop until you have received as many bytes as you need.

usr
  • 168,620
  • 35
  • 240
  • 369
  • Unclear where the downvote is coming from. This answer is correct. Maybe a passerby did not understand the technical issue?! – usr Aug 19 '16 at 11:19
2

@usr is completely right about whe way stream read should be implemented, and that id you dont't expect anything. On the other side what happened to me was same happened to @Bubba. Code was, working and now it's not. Reason? Microsoft update for .net framework. More details here: https://connect.microsoft.com/VisualStudio/feedback/details/2590316/windows-10-update-kb3147458-changes-behavior-of-sslstream-read-beginread-endread

100r
  • 1,099
  • 1
  • 12
  • 24
  • `Code was, working and now it's not` it was working by coincidence but it was broken to begin with. The update brought your bug to light. It is valuable to understand why it's breaking *now*, though. – usr Aug 19 '16 at 11:19
  • Exactly. But, that can be pretty shocking when update smash you like that. – 100r Aug 19 '16 at 12:29
-1

I am experiencing the same problem. The code was working several weeks ago - now it's not working. I wonder if one of the Microsoft updates broke it?

I created a work around (hack) - until I can figure out what the problem is: (at the class level)

string previousChar = null;

(in the callback function for TcpClient.GetStream.Begin)

        if ((previousChar == null) && (bytesRead == 1))
        {
            previousChar = Encoding.ASCII.GetString(readBuffer, 0, bytesRead);
        }
        // Convert the byte array the message was saved into
        if (bytesRead > 6)
        {
            message = Encoding.ASCII.GetString(readBuffer, 0, bytesRead);
            if (previousChar != null)
            {
                message = previousChar + message;
                previousChar = null;
            }
Bubba
  • 192
  • 1
  • 3
  • 14
  • My answer should cover your issue. – usr May 13 '16 at 17:15
  • Date of this update is verry similar to your questions date :) https://support.microsoft.com/en-us/kb/3142037 – 100r May 23 '16 at 00:24
  • This answer is incorrect. It might *mask* the issue but it does not properly fix it. SslStream does not promise to read the requested number of bytes. It never did promise that. Calling code must deal with that. This Windows update only brought the bug to light causing my customers to complain. – usr Aug 19 '16 at 11:22