StreamingSocket and DatagramSocket Not Functioning Correctly


#1

StreamingSocket and DatagramSocket are two of JUCE’s ways of connecting over a local network, or over the Internet with TCP or UDP. However, they do not work for me, even with the most stripped-down implementations.

StreamingSocket returns -1 when I use getBoundPort(), although I have set a port with bindToPort(). What’s really a mystery is that DatagramSocket, when done the exact same way, does return the port when using getBoundPort() after using bindToPort(). However, when you take the next step with DatagramSocket and use waitUntilReady(), it does not work as expected. If I put waitUntilReady() into true/reading mode, it always returns a value of 0 meaning it fails, while false/writing mode returns a value of 1 meaning it succeeds.

I’ve got it down to a few lines of code, to simplify and isolate things. For our actual implementation, we will not do it like this.

Testing StreamingSocket

In PluginProcessor.h, in the public section I made a StreamingSocket ScopedPointer:

ScopedPointer<StreamingSocket> SocketConnection;

In PluginProcessor.cpp, in the constructor, I did this:

SocketConnection = new StreamingSocket;
SocketConnection->bindToPort(5575);

Quick and dirty paint() in PluginEditor.cpp:

g.drawSingleLineText (String("Local Port Number Binded To:  " + String(processor.SocketConnection->getBoundPort())), getWidth()/2, getHeight()/6*2, Justification::centred);
g.drawSingleLineText (String("Wait Until Ready Result:  " + String(processor.SocketConnection->waitUntilReady(true, 5000))), getWidth()/2, getHeight()/6*3, Justification::centred);

In AudioMulch I get this:

Quick note to future readers: I tried this in PluginEditor.h/cpp instead of PluginProcessor and it would crash whenever I used ScopedPointer to create the StreamingSocket/DatagramSocket objects. However it would work if I used a regular pointer (e.g. DatagramSocket* SocketConnection). There was a jassert that made it seem like it was related to the way PluginEditor works, so I tried in PluginProcessor and it worked there

Testing DatagramSocket

Ok, we do the same thing with DatagramSocket and get different results.

In PluginProcessor.h, in the public section I made a DatagramSocket ScopedPointer:

ScopedPointer<DatagramSocket> SocketConnection;

In PluginProcessor.cpp, in the constructor, I did this:

SocketConnection = new DatagramSocket;
SocketConnection->bindToPort(5575);

I had the same contents in PluginEditor.cpp’s paint() function as in the StreamingSocket example above, and I get this result:

Change the waitUntilReady() parameters from true:

g.drawSingleLineText (String("Wait Until Ready Result:  " + String(processor.SocketConnection->waitUntilReady(true, 5000)))

To false:

g.drawSingleLineText (String("Wait Until Ready Result:  " + String(processor.SocketConnection->waitUntilReady(true, 5000)))

And you get success, indicated by the result “1”, however only in this false/writing mode, not in true/reading mode:

What next?

So what do I need to do to get StreamingSocket and DatagramSocket working as they should?


#2

Hi Gebre,

Are you checking the return value of bindToPort? Make sure it returns true.

Also, I’m not sure if waitUntilReady is correct. You typically call waitUntilReady when your sockect is in a state to read or write. As the socket hasn’t connected to anything yet waitUntilReady will always return -1.

If you are trying to use the SocketConnection as a “server”, i,e. it listens on port 5575 and waits for incoming connections, then you should be using createListener and waitForNextConnection. After which you can call waitUntilReady on the return value of the latter.

If you are trying to use the SocketConnection as a “client” then you need to call connect before calling waitUntilReady. However, I think Windows will always assign a random port number when using a StreamingSocket in client mode, so calling bindToPort may not make a difference. However, it’s definitely possible to get the port after the socket has connected.


#3

That gets us closer, this time with StreamingSocket, the port is returned as expected with getBoundPort().

Using createListener instead of bindToPort() makes getBoundPort() return the port as would be expected.

//SocketConnection->bindToPort(5575);
SocketConnection->createListener(5575);

Here is the result:

Connection Problem

The problem now is that I cannot get a connection between two computers on my local network to actually happen.

On the client I have:

PluginProcessor .h:

ScopedPointer<StreamingSocket> SocketConnection;

PluginProcessor.cpp (In the constructor to make a simple demo):

SocketConnection = new StreamingSocket;
connectStatus = SocketConnction->connect("192.168.1.66", 5575, 3000);

On the host/server I have:

PluginProcessor .h:

ScopedPointer<StreamingSocket> SocketConnection;

PluginProcessor.cpp (In the constructor to make a simple demo):

SocketConnection->createListener(5575);
SocketConnection->waitForNextConnection();

I also tried (among a ton of other things):

SocketConnection->createListener(5575, "192.168.1.66");
SocketConnection->waitForNextConnection();

The connect function never returns true, isConnected is never true. I’ve tried a ton of different things. I’m assuming the &remoteHostname of connect is supposed to be the IP address, as I have seen it that way in some forum examples.

I also noticed that waitForNextConnection() returns a new StreamingSocket object, not sure how to call waitUntilReady on that return value.

I have done it this stripped-down way to get it to its most basic form so it might be easiest to diagnose here on the forum. When it works as expected I will do this in a separate thread. I think this thread, when complete, will serve as great documentation on this class.


#4

Could be an issue with your firewall? I just tried this and it works for me.