DatagramSocket::bindToPort() not working


#1

Hello,

 

I'm trying to make a DataSocket (which is listening to OSC messages) bind to a port entered by the user in a TextEditor. For some reason the bindtoPort() method seems to not be doing anything and the socket stays bound to the original port. This is in the run() section of the Thread that is listening to the messages:

if (oldPort != port) {

            bool newPort = dataSocket.bindToPort(port);

            oldPort = port;

}

I added a break at the bindToPort call and it indeed gets called with the newly entered port number but dataSocket remains bound to the port that was used at definition. Do I have to do something else in order to make it change? I'm on OS X and using latest Juce.

 

Thanks,

 

Hector

 


#2

Hmm.. Well, it call ::bind and passes the new port number.. I'm a bit stumped as to why it wouldn't work. Have you stepped through the implementation to see exactly what happens in there?


#3

Hi Jules,

Thank you for your reply. 

Trying to change the port from the initial value of 8001 to 8005, I stepped through and found that everything seemed to follow the right flow except that bindSocketToPort in juce_Socket.cpp returned false:

return bind (handle, (struct sockaddr*) &servTmpAddr, sizeof (struct sockaddr_in)) >= 0;

====== These are the values at this point:

handle    const SocketHandle    8
servTmpAddr    sockaddr_in    {...}
    sin_len    __uint8_t    0 '\000'
    sin_family    sa_family_t    2 '\002'
    sin_port    in_port_t    17695
    sin_addr    in_addr    {...}
        sin_addr    in_addr    {...}
    sin_zero    char [8]    [8]
        0    char    0 '\000'
        1    char    0 '\000'
        2    char    0 '\000'
        3    char    0 '\000'
        4    char    0 '\000'
        5    char    0 '\000'
        6    char    0 '\000'
        7    char    0 '\000'


 

I'm not sure why sin_port equals 17695 instead of 8005.

EDIT: OK, I get it now. 8005 is being bit swaped by OSSwapInt16()

Also, what I noticed is that eventhough I succesfully initialized dataSocket with a port of 8001 (data is received properly on that port), datSocket's contents are (before trying to change the port):


dataSocket    'juce::DatagramSocket'    {...}
    hostName    'juce::String'    {...}
        text    CharPointerType    {...}
            data    CharType *    0x10b1828d0
                *data    char    0 '\0'
    portNumber    volatile int    0
    handle    volatile int    8
    connected    bool    true
    allowBroadcast    bool    false
    serverAddress    void *    0x0
    leakDetector301    'juce::LeakedObjectDetector<juce::DatagramSocket>'    {...}
 

Shouldn't portNumber be equal to 8001?

 

Thanks again, please let me know if you neeed any extra information to help me figure this out.

 

Best,

 

Hector


#4

TBH I really don't know, I'm not much of a sockets expert.. If bind simply refuses to bind the new port number, then there must be a reason. Perhaps it just doesn't support that? Why not just open the socket on the correct port to begin with?


#5

Hi Jules,

I got it solved!

There is not correct port number. The idea is to give the user a choice of port for receiving OSC messages.

On further investigation, I printed the value of errno right after the bindToPort() call and I got errno 22, wich is "Invalid Argument" wich for bind() means "The socket is already bound to an address".  Also found on a thread in the Apple developers mailing list that you have to close the socket before being able to bind it to a different port. 

So I made it work by first calling dataSocket.close() then dataSocket = new DatagramSocket(port);

 

Best,

 

Hector