CyberFox
CyberFox

Reputation: 810

Sockets. Properly getting the response

I have an issues with my http requests 'sometimes' failing.

var bodyBuilder = new List<byte>(4096);
var buffer = new byte[256];
while (socket.Available > 0) {
    var responseLength = socket.Receive(buffer, buffer.Length, SocketFlags.None);

    for (var i = 0; i < responseLength; i++)
        bodyBuilder.Add(buffer[i]);

    if (responseLength == 0)
        break; // never true btw
}

i read that socket.Available > 0 should not be used since it doesn't indicate whether a socket is finished or not, but whether "if there is data this time" https://www.coderanch.com/how-to/java/AvailableDoesntDoWhatYouThinkItDoes (albeit not C#, and not Sockets)

It makes sense because I'm getting exceptions when attempting to parse the response. Even when stepping through manually the debugger the data is receieve properly because i do it slowly when i step through

The solution would be to replace while (socket.Available > 0) with while (true) because the responseLength will be 0 once the server closes the connection. (according to many sources) But that is NOT what is happening. If i execute socket.Recieve() and there is no data available. The socket simply blocks indefinitely.

Any help?

Upvotes: 0

Views: 91

Answers (1)

usr
usr

Reputation: 171168

Yes, Available must be removed. A socket should usually have a single read outstanding. There should not be any check if there is data. Just read and work with the result.

If i execute socket.Recieve() and there is no data available. The socket simply blocks indefinitely.

This means... that there is no data available. The other side has not sent more than what you already read.

You can solve this is two ways:

  1. Determine that there is no more data through the protocol. For example, length-prefix your data. Then, you know how much to read.
  2. Make the other side shut down the socket so that your read will end and return zero bytes read.

Upvotes: 2

Related Questions