Issues with socket binding and connecting


#1

Hi everybody,

I'm currently developing a client/server-system that is based on VST plugins on both ends.

Originally I experimented with UDP sockets but somehow the server did not get any messages from the client. I then tried TCP sockets with less success, they neither bind to a port nor connect.

To make sure it was not a VST specific problem I created a standalone application that does nothing but trying to bind a TCP socket and connect it:

socket = new StreamingSocket();
bool bound = socket->bindToPort (12345);
bool connected = socket->connect ("127.0.0.1", 12346, 0);

The socket does not bind, I tried every port greater than 1024 as well. connect() with a timeout of 0 returns immediately, trying several seconds does not help either. I tested both on Windows 8.1 x64 and Windows 7 SP1 x64, so it might be a platform specific issue.

I don't really see where this is coming from since the JUCE socket class seems to be rather simple to use though I have to admit that I'm new to C++ and JUCE.

 

I'd be happy if anybody could help, thanks in advance!

Jannick


#2

Remember, the classes are just lightweight wrappers for typical Berkley Sockets.

Once you have bound a TCP socket to a port you would use that socket to receive and accept connections. You can't use that exact same socket to initiate a connection. You might want to read a tutorial on Sockets basics, then take another look at the wrapper classes.


#3

Thanks, I didn't realize I had to put one socket in listening mode before establishing a connection from a second socket.

For now I am able to connect one socket to a another but unfortunately the binding issue persists.


#4

I'm not sure I understand what you mean by a binding problem. For a UDP socket you would typically use sendto and recvfrom.

On a streaming socket you bind before receiving connections. Opens to that target IP:port should generate new connection requests. If you are getting a TCP socket connection going, it is hard to understand what binding problem remains.


#5

That's exactly what I thought: I wanted to bind the socket before putting it into listener mode by calling createListener(), just to make sure that I know the port to connect to. The socket still does not bind to a port though a connection can be established. Somehow the binding doesn't seem to be necessary but I'll be looking further into it.


#6

If you create a listener:

bool StreamingSocket::createListener (const int newPortNumber, const String& localHostName)

You are passing in a port number. If you look in juce_Socket.cpp at the function you will see that it calls bind for you:

    if (bind (handle, (struct sockaddr*) &servTmpAddr, sizeof (struct sockaddr_in)) < 0
         || listen (handle, SOMAXCONN) < 0)
    {
        close();
        return false;
    }
    connected = true;
    return true;

So if you try to bind the socket again, it will fail.


#7

Ok, I see. But then it is even stranger that bindSocketToPort() doesn't work when called before the listener is being created, since the binding seems to be successful when createListener() is called.

Anyway, thanks for helping out! Hope I'll get my system running.


#8

It would depend on what constructor your called to create the socket originally and any subsequent calls. 

Again, calls like StreamingSocket::bindToPort are very simple, it just calls a helper function with the socket handle, which creates an address structure of IPANY and the target port. If "bind" fails, it is the condition of the socket when you call. 

Also be careful how you check result. bind() natively returns 0 for success, a negative value for erorr. But the helper returns true for success, false for failure.


#9

I'm creating the socket like this (not by calling bindSocketToPort(), I was looking at the socket class when I wrote this and obviously got a little bit confused):

StreamingSocket* socket = new StreamingSocket();
bool binding = socket->bindToPort (localPortNumber);
bool listener = socket->createListener (localPortNumber, localHostName);

After that I check both boolean values, in this scenario binding is 0 and listener is 1.