StreamingSocket problem


#1

Hi,
I noticed a message back in March which I think referenced this same problem http://rawmaterialsoftware.com/juceforum/viewtopic.php?t=2727&highlight=streamingsocket ( i think). But what appears to be happening is that unless the size of an individual packet is the same or greater than the maxBytesToRead argument to the read() method, read() will not return and will not write to the destination buffer. This is unless several packets have been sent which cumulatively equal the size of maxBytesToRead. Looking at the code for readSocket in juce_Socket.cpp this seems to be the logic being expressed as it continues to read while the bytesRead < maxBytesToRead.

If this is what is meant then perhaps maxBytesToRead should be changed to minBytesToRead and another method could be made available that does what might be more commonly expected which is to block until a packet is received at which time it is written into the destBuffer up to maxBytesToRead.


#2

You have waitUntilReady method for just that purpose (wait until there is data to read).

The issue with read is that it must almost follow other “stream” read’s semantic.
If you ask to read on a file with 100 bytes, you expect 100 bytes, or an error (likely end-of-file).

You’ll get the same behaviour with readSocket (read the asked amount of bytes, or fail with error (likely socket closed, or timeout)).

It’s the behaviour inherited from old socket code.

What you are more interested in is recv semantic, ie, get what’s to get and return ASAP. It’s not done actually in current code, but surely could be added.


#3

thanks. so is there no current way to simply read a variable length packet using this class? i also notice it kills all my networking while it is blocking on the read, which is bad.


#4

It’s O/S.
Just add a method “recvSocket” that does the inner loop of readSocket, but be prepared of the potential return code.

Concerning the blocking state, read blocks until it has enough data.
Use your own recvSocket method, and use waitUntilReady before calling this method to know if you’re going to block or not.

I guess Jules could add the method.
I have another question to Jules, why is there a #ifdef WIN32 on the recv part of read socket (both linux and mac have recv function as it’s posix) ?


#5

[quote=“X-Ryl669”]It’s O/S.
I have another question to Jules, why is there a #ifdef WIN32 on the recv part of read socket (both linux and mac have recv function as it’s posix) ?[/quote]

I think there was some problem with a particular version of OSX, maybe 10.2 or something. It could probably be removed now.


#6

[quote=“X-Ryl669”]
What you are more interested in is recv semantic, ie, get what’s to get and return ASAP. It’s not done actually in current code, but surely could be added.[/quote]

you are correct i was expecting the recv semantic but can see how this is inline with other streams in juce. i think that the recv semantic should be added as it is quite useful.


#7

Ok, in that case, simply add this:

static int recvSocket (const int handle, void* const destBuffer, const int maxBufferSize) throw()
{
    int bytesRead = 0;


    bytesRead = recv (handle, ((char*) destBuffer), maxBufferSize, 0);
    if (bytesRead == 0) bytesRead = -1;

    return bytesRead;
}

int StreamingSocket::recv (void* destBuffer, const int bufferSize)
{
    return (connected && ! isListener) ? recvSocket (handle, destBuffer, bufferSize) : -1;
}